diff --git a/.gitignore b/.gitignore index f515257..158865a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ - -games/FNaFB1/Save01.rvdata2 +games/FNaFB1/Save*.rvdata2 +games/FNaFB2/Save*.rvdata2 worlds/fnafb1.apworld -games/FNaFB1/Save03.rvdata2 -games/FNaFB1/Save02.rvdata2 -games/FNaFB1/Save01.rvdata2.bak +worlds/fnafb2.apworld diff --git a/README.md b/README.md index bb12aa3..580dbf7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Do note that this game is not, and never will be, supported by the main Archipelago team. This game is not permitted to be run or discussed in the official Archipelago Discord servers under any circumstances. -# Changes to base game +# Changes to base game of FNaFB1 Some changes were made to make playing this randomizer a more seamless experience. Here's what you need to know. - Characters, Weapons, Armors, Key Items, and B.B. Shops have been shuffled into the item pool to find. - The Kingly/Godly Weapons have been removed from the RNG drops in place of Vouchers to be traded in on the Show Stage for checks (if enabled in the player's YAML). @@ -20,6 +20,18 @@ - The Puppet no longer has a timer and can be fought by interacting with it in the Restrooms. - Interior Walls will only open if the "Reveal Interior Walls" item has been recieved by the player. - The door to The Office requires 4 Key Pieces to be obtained before you're allowed to enter. You must also defeat all of the cameras as normal. + +# Changes to base game of FNaFB2 + - Every change from FNaFB1 were implemented into here with a couple of differences. + - Real Weapons have been removed from the RNG drops for vouchers if the setting is enabled. + - B.B. Shops work the same as the FNaFB1 AP with the order being Main Hall B.B., Party Room 3 B.B., Kid's Cove B.B., Office B.B. + - Both First and Second Puppet can be fought by interacting with it in either the Show Stage or the Women's Bathroom + - The door to the Cave of the Past requires 4 B.B.'s Essence. + - Mangle will no longer prevent you from shattering your masculinity before you enter the Women's Bathroom. + - Toy Bonnie will still appear in the right vent if you get Toy Bonnie before you talk/free him. + - Shadow Bonnie bossfight will appear if you have toy animatronics in your party, but they will be removed before you fight it. + - Cake Minigame has been reduced to 10 times to feed the kid from 100. + - The final cassette will no longer auto warp you to the rap god. There is another cassette in the bottom right corner of the Office for you to fight the rap god. # APWorld Setup This randomizer uses [Archipelago](https://github.com/ArchipelagoMW/Archipelago) to handle seed generation. diff --git a/games/FNaFB1/Data/Actors.rvdata2 b/games/FNaFB1/Data/Actors.rvdata2 index 4d20b29..cdc7b0d 100644 Binary files a/games/FNaFB1/Data/Actors.rvdata2 and b/games/FNaFB1/Data/Actors.rvdata2 differ diff --git a/games/FNaFB1/Data/Animations.rvdata2 b/games/FNaFB1/Data/Animations.rvdata2 index 1ae12a3..11b0480 100644 Binary files a/games/FNaFB1/Data/Animations.rvdata2 and b/games/FNaFB1/Data/Animations.rvdata2 differ diff --git a/games/FNaFB1/Data/Armors.rvdata2 b/games/FNaFB1/Data/Armors.rvdata2 index 7126abe..88d8d7c 100644 Binary files a/games/FNaFB1/Data/Armors.rvdata2 and b/games/FNaFB1/Data/Armors.rvdata2 differ diff --git a/games/FNaFB1/Data/Classes.rvdata2 b/games/FNaFB1/Data/Classes.rvdata2 index 23dc4fa..459a132 100644 Binary files a/games/FNaFB1/Data/Classes.rvdata2 and b/games/FNaFB1/Data/Classes.rvdata2 differ diff --git a/games/FNaFB1/Data/Enemies.rvdata2 b/games/FNaFB1/Data/Enemies.rvdata2 index 7abf68f..2182cc3 100644 Binary files a/games/FNaFB1/Data/Enemies.rvdata2 and b/games/FNaFB1/Data/Enemies.rvdata2 differ diff --git a/games/FNaFB1/Data/Items.rvdata2 b/games/FNaFB1/Data/Items.rvdata2 index b4e072f..68672eb 100644 Binary files a/games/FNaFB1/Data/Items.rvdata2 and b/games/FNaFB1/Data/Items.rvdata2 differ diff --git a/games/FNaFB1/Data/Map001.rvdata2 b/games/FNaFB1/Data/Map001.rvdata2 index ca26449..9f965af 100644 Binary files a/games/FNaFB1/Data/Map001.rvdata2 and b/games/FNaFB1/Data/Map001.rvdata2 differ diff --git a/games/FNaFB1/Data/Map006.rvdata2 b/games/FNaFB1/Data/Map006.rvdata2 index 8ea4dd6..773c1cd 100644 Binary files a/games/FNaFB1/Data/Map006.rvdata2 and b/games/FNaFB1/Data/Map006.rvdata2 differ diff --git a/games/FNaFB1/Data/Map011.rvdata2 b/games/FNaFB1/Data/Map011.rvdata2 index 38d4c20..bf525cb 100644 Binary files a/games/FNaFB1/Data/Map011.rvdata2 and b/games/FNaFB1/Data/Map011.rvdata2 differ diff --git a/games/FNaFB1/Data/MapInfos.rvdata2 b/games/FNaFB1/Data/MapInfos.rvdata2 index 623bf53..861da09 100644 Binary files a/games/FNaFB1/Data/MapInfos.rvdata2 and b/games/FNaFB1/Data/MapInfos.rvdata2 differ diff --git a/games/FNaFB1/Data/Scripts.rvdata2 b/games/FNaFB1/Data/Scripts.rvdata2 index acaa4d7..c6e57d3 100644 Binary files a/games/FNaFB1/Data/Scripts.rvdata2 and b/games/FNaFB1/Data/Scripts.rvdata2 differ diff --git a/games/FNaFB1/Data/Skills.rvdata2 b/games/FNaFB1/Data/Skills.rvdata2 index e243419..dd8109a 100644 Binary files a/games/FNaFB1/Data/Skills.rvdata2 and b/games/FNaFB1/Data/Skills.rvdata2 differ diff --git a/games/FNaFB1/Data/States.rvdata2 b/games/FNaFB1/Data/States.rvdata2 index 77dd2b5..885d7a9 100644 Binary files a/games/FNaFB1/Data/States.rvdata2 and b/games/FNaFB1/Data/States.rvdata2 differ diff --git a/games/FNaFB1/Data/System.rvdata2 b/games/FNaFB1/Data/System.rvdata2 index 69ce04e..19e615d 100644 Binary files a/games/FNaFB1/Data/System.rvdata2 and b/games/FNaFB1/Data/System.rvdata2 differ diff --git a/games/FNaFB1/Data/Tilesets.rvdata2 b/games/FNaFB1/Data/Tilesets.rvdata2 index bb52248..8e8e15c 100644 Binary files a/games/FNaFB1/Data/Tilesets.rvdata2 and b/games/FNaFB1/Data/Tilesets.rvdata2 differ diff --git a/games/FNaFB1/Data/Weapons.rvdata2 b/games/FNaFB1/Data/Weapons.rvdata2 index 1ccf7b3..ac50e02 100644 Binary files a/games/FNaFB1/Data/Weapons.rvdata2 and b/games/FNaFB1/Data/Weapons.rvdata2 differ diff --git a/games/FNaFB1/mkxp.json b/games/FNaFB1/mkxp.json index c018471..d793d5c 100644 --- a/games/FNaFB1/mkxp.json +++ b/games/FNaFB1/mkxp.json @@ -6,6 +6,6 @@ // Please specify where your RTP (Runtime Package) is in case it isn't in the default location. // Make sure to escape any backslashes (\, write these as \\) // Default: [ "C:\\Program Files (x86)\\Common Files\\Enterbrain\\RGSS3\\RPGVXAce" ] - "RTP": [ "D:\\RPGVXAce" ], + "RTP": [ "C:\\Program Files (x86)\\Common Files\\Enterbrain\\RGSS3\\RPGVXAce" ], } diff --git a/games/FNaFB2/Custom/Graphics/Pictures/text_input.png b/games/FNaFB2/Custom/Graphics/Pictures/text_input.png new file mode 100644 index 0000000..99bfba6 Binary files /dev/null and b/games/FNaFB2/Custom/Graphics/Pictures/text_input.png differ diff --git a/games/FNaFB2/Data/Armors.rvdata2 b/games/FNaFB2/Data/Armors.rvdata2 index 5865ec4..a0d9a8a 100644 Binary files a/games/FNaFB2/Data/Armors.rvdata2 and b/games/FNaFB2/Data/Armors.rvdata2 differ diff --git a/games/FNaFB2/Data/Classes.rvdata2 b/games/FNaFB2/Data/Classes.rvdata2 index d97137c..f174604 100644 Binary files a/games/FNaFB2/Data/Classes.rvdata2 and b/games/FNaFB2/Data/Classes.rvdata2 differ diff --git a/games/FNaFB2/Data/CommonEvents.rvdata2 b/games/FNaFB2/Data/CommonEvents.rvdata2 index 0a8232a..957715b 100644 Binary files a/games/FNaFB2/Data/CommonEvents.rvdata2 and b/games/FNaFB2/Data/CommonEvents.rvdata2 differ diff --git a/games/FNaFB2/Data/Enemies.rvdata2 b/games/FNaFB2/Data/Enemies.rvdata2 index 5ad9e41..6476090 100644 Binary files a/games/FNaFB2/Data/Enemies.rvdata2 and b/games/FNaFB2/Data/Enemies.rvdata2 differ diff --git a/games/FNaFB2/Data/Items.rvdata2 b/games/FNaFB2/Data/Items.rvdata2 index b2d1226..d8bcd27 100644 Binary files a/games/FNaFB2/Data/Items.rvdata2 and b/games/FNaFB2/Data/Items.rvdata2 differ diff --git a/games/FNaFB2/Data/Map013.rvdata2 b/games/FNaFB2/Data/Map013.rvdata2 index 00e1eaf..c6528bb 100644 Binary files a/games/FNaFB2/Data/Map013.rvdata2 and b/games/FNaFB2/Data/Map013.rvdata2 differ diff --git a/games/FNaFB2/Data/Map017.rvdata2 b/games/FNaFB2/Data/Map017.rvdata2 index ec85207..750edd1 100644 Binary files a/games/FNaFB2/Data/Map017.rvdata2 and b/games/FNaFB2/Data/Map017.rvdata2 differ diff --git a/games/FNaFB2/Data/Map018.rvdata2 b/games/FNaFB2/Data/Map018.rvdata2 index 616fd92..f258906 100644 Binary files a/games/FNaFB2/Data/Map018.rvdata2 and b/games/FNaFB2/Data/Map018.rvdata2 differ diff --git a/games/FNaFB2/Data/Map019.rvdata2 b/games/FNaFB2/Data/Map019.rvdata2 index 344ae7c..3a50e9a 100644 Binary files a/games/FNaFB2/Data/Map019.rvdata2 and b/games/FNaFB2/Data/Map019.rvdata2 differ diff --git a/games/FNaFB2/Data/Map020.rvdata2 b/games/FNaFB2/Data/Map020.rvdata2 index fc8794c..525b35a 100644 Binary files a/games/FNaFB2/Data/Map020.rvdata2 and b/games/FNaFB2/Data/Map020.rvdata2 differ diff --git a/games/FNaFB2/Data/Map021.rvdata2 b/games/FNaFB2/Data/Map021.rvdata2 index dca233a..518f4eb 100644 Binary files a/games/FNaFB2/Data/Map021.rvdata2 and b/games/FNaFB2/Data/Map021.rvdata2 differ diff --git a/games/FNaFB2/Data/Map022.rvdata2 b/games/FNaFB2/Data/Map022.rvdata2 index 98788ef..047bd70 100644 Binary files a/games/FNaFB2/Data/Map022.rvdata2 and b/games/FNaFB2/Data/Map022.rvdata2 differ diff --git a/games/FNaFB2/Data/Map023.rvdata2 b/games/FNaFB2/Data/Map023.rvdata2 index aefb72c..8ed5efd 100644 Binary files a/games/FNaFB2/Data/Map023.rvdata2 and b/games/FNaFB2/Data/Map023.rvdata2 differ diff --git a/games/FNaFB2/Data/Map024.rvdata2 b/games/FNaFB2/Data/Map024.rvdata2 index 690bbac..3ebbde8 100644 Binary files a/games/FNaFB2/Data/Map024.rvdata2 and b/games/FNaFB2/Data/Map024.rvdata2 differ diff --git a/games/FNaFB2/Data/Map025.rvdata2 b/games/FNaFB2/Data/Map025.rvdata2 index 22afac9..1d7076a 100644 Binary files a/games/FNaFB2/Data/Map025.rvdata2 and b/games/FNaFB2/Data/Map025.rvdata2 differ diff --git a/games/FNaFB2/Data/Map026.rvdata2 b/games/FNaFB2/Data/Map026.rvdata2 index 5894ac4..d999ff6 100644 Binary files a/games/FNaFB2/Data/Map026.rvdata2 and b/games/FNaFB2/Data/Map026.rvdata2 differ diff --git a/games/FNaFB2/Data/Map027.rvdata2 b/games/FNaFB2/Data/Map027.rvdata2 index ee3bbb1..4c92908 100644 Binary files a/games/FNaFB2/Data/Map027.rvdata2 and b/games/FNaFB2/Data/Map027.rvdata2 differ diff --git a/games/FNaFB2/Data/Map028.rvdata2 b/games/FNaFB2/Data/Map028.rvdata2 index 21349f4..733661a 100644 Binary files a/games/FNaFB2/Data/Map028.rvdata2 and b/games/FNaFB2/Data/Map028.rvdata2 differ diff --git a/games/FNaFB2/Data/Map029.rvdata2 b/games/FNaFB2/Data/Map029.rvdata2 index 35eaa6b..92b829c 100644 Binary files a/games/FNaFB2/Data/Map029.rvdata2 and b/games/FNaFB2/Data/Map029.rvdata2 differ diff --git a/games/FNaFB2/Data/Map030.rvdata2 b/games/FNaFB2/Data/Map030.rvdata2 index 99a1499..ea804db 100644 Binary files a/games/FNaFB2/Data/Map030.rvdata2 and b/games/FNaFB2/Data/Map030.rvdata2 differ diff --git a/games/FNaFB2/Data/Map031.rvdata2 b/games/FNaFB2/Data/Map031.rvdata2 index 8849e62..8586b0b 100644 Binary files a/games/FNaFB2/Data/Map031.rvdata2 and b/games/FNaFB2/Data/Map031.rvdata2 differ diff --git a/games/FNaFB2/Data/Map032.rvdata2 b/games/FNaFB2/Data/Map032.rvdata2 index f399c33..439376d 100644 Binary files a/games/FNaFB2/Data/Map032.rvdata2 and b/games/FNaFB2/Data/Map032.rvdata2 differ diff --git a/games/FNaFB2/Data/Map033.rvdata2 b/games/FNaFB2/Data/Map033.rvdata2 index 076d2f7..74a4b35 100644 Binary files a/games/FNaFB2/Data/Map033.rvdata2 and b/games/FNaFB2/Data/Map033.rvdata2 differ diff --git a/games/FNaFB2/Data/Map034.rvdata2 b/games/FNaFB2/Data/Map034.rvdata2 index 7bd1bd3..d5daa73 100644 Binary files a/games/FNaFB2/Data/Map034.rvdata2 and b/games/FNaFB2/Data/Map034.rvdata2 differ diff --git a/games/FNaFB2/Data/Map035.rvdata2 b/games/FNaFB2/Data/Map035.rvdata2 index 4292a82..116e3ce 100644 Binary files a/games/FNaFB2/Data/Map035.rvdata2 and b/games/FNaFB2/Data/Map035.rvdata2 differ diff --git a/games/FNaFB2/Data/Map036.rvdata2 b/games/FNaFB2/Data/Map036.rvdata2 index a35fa63..185c105 100644 Binary files a/games/FNaFB2/Data/Map036.rvdata2 and b/games/FNaFB2/Data/Map036.rvdata2 differ diff --git a/games/FNaFB2/Data/Map037.rvdata2 b/games/FNaFB2/Data/Map037.rvdata2 index 7c3dc1a..5a06116 100644 Binary files a/games/FNaFB2/Data/Map037.rvdata2 and b/games/FNaFB2/Data/Map037.rvdata2 differ diff --git a/games/FNaFB2/Data/Map038.rvdata2 b/games/FNaFB2/Data/Map038.rvdata2 index 733ea3f..f03313d 100644 Binary files a/games/FNaFB2/Data/Map038.rvdata2 and b/games/FNaFB2/Data/Map038.rvdata2 differ diff --git a/games/FNaFB2/Data/Map039.rvdata2 b/games/FNaFB2/Data/Map039.rvdata2 index 9ca7f71..dd34414 100644 Binary files a/games/FNaFB2/Data/Map039.rvdata2 and b/games/FNaFB2/Data/Map039.rvdata2 differ diff --git a/games/FNaFB2/Data/Map040.rvdata2 b/games/FNaFB2/Data/Map040.rvdata2 index a0df4af..2a7167f 100644 Binary files a/games/FNaFB2/Data/Map040.rvdata2 and b/games/FNaFB2/Data/Map040.rvdata2 differ diff --git a/games/FNaFB2/Data/Map050.rvdata2 b/games/FNaFB2/Data/Map050.rvdata2 index 6816629..006fdc7 100644 Binary files a/games/FNaFB2/Data/Map050.rvdata2 and b/games/FNaFB2/Data/Map050.rvdata2 differ diff --git a/games/FNaFB2/Data/MapInfos.rvdata2 b/games/FNaFB2/Data/MapInfos.rvdata2 index 8034c1a..c1e88bf 100644 Binary files a/games/FNaFB2/Data/MapInfos.rvdata2 and b/games/FNaFB2/Data/MapInfos.rvdata2 differ diff --git a/games/FNaFB2/Data/Scripts.rvdata2 b/games/FNaFB2/Data/Scripts.rvdata2 index 8c47f27..e7e3fca 100644 Binary files a/games/FNaFB2/Data/Scripts.rvdata2 and b/games/FNaFB2/Data/Scripts.rvdata2 differ diff --git a/games/FNaFB2/Data/Skills.rvdata2 b/games/FNaFB2/Data/Skills.rvdata2 index 1421d47..49bdb90 100644 Binary files a/games/FNaFB2/Data/Skills.rvdata2 and b/games/FNaFB2/Data/Skills.rvdata2 differ diff --git a/games/FNaFB2/Data/System.rvdata2 b/games/FNaFB2/Data/System.rvdata2 index 9e4150e..0df99e6 100644 Binary files a/games/FNaFB2/Data/System.rvdata2 and b/games/FNaFB2/Data/System.rvdata2 differ diff --git a/games/FNaFB2/Fonts/courbd.ttf b/games/FNaFB2/Fonts/courbd.ttf new file mode 100644 index 0000000..a4f26b4 Binary files /dev/null and b/games/FNaFB2/Fonts/courbd.ttf differ diff --git a/games/FNaFB2/Game.exe b/games/FNaFB2/Game.exe index d8c4c30..66a4de7 100644 Binary files a/games/FNaFB2/Game.exe and b/games/FNaFB2/Game.exe differ diff --git a/games/FNaFB2/Game.ini b/games/FNaFB2/Game.ini index 571bcbc..26764e7 100644 --- a/games/FNaFB2/Game.ini +++ b/games/FNaFB2/Game.ini @@ -2,7 +2,7 @@ RTP=RPGVXAce Library=System\RGSS301.dll Scripts=Data\Scripts.rvdata2 -Title=Five Nights at Fuckboy's 2: Final Mix: Game of the Year (GameJolt ver.) +Title=Five Nights at Fuckboy's 2 Archipelago Description=(no description) CreationDate=1723082741 [Fullscreen++] diff --git a/games/FNaFB2/Graphics/Characters/APTrade.png b/games/FNaFB2/Graphics/Characters/APTrade.png new file mode 100644 index 0000000..5e90113 Binary files /dev/null and b/games/FNaFB2/Graphics/Characters/APTrade.png differ diff --git a/games/FNaFB2/Graphics/System/IconSet.png b/games/FNaFB2/Graphics/System/IconSet.png new file mode 100644 index 0000000..06341dc Binary files /dev/null and b/games/FNaFB2/Graphics/System/IconSet.png differ diff --git a/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/ClassMethods/cdesc-ClassMethods.ri b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/ClassMethods/cdesc-ClassMethods.ri new file mode 100644 index 0000000..82ce19c Binary files /dev/null and b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/ClassMethods/cdesc-ClassMethods.ri differ diff --git a/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/__events-i.ri b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/__events-i.ri new file mode 100644 index 0000000..e802de5 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/__events-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/add_listener-i.ri b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/add_listener-i.ri new file mode 100644 index 0000000..1c19c31 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/add_listener-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/cdesc-InstanceMethods.ri b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/cdesc-InstanceMethods.ri new file mode 100644 index 0000000..20f84d6 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/cdesc-InstanceMethods.ri differ diff --git a/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/emit-i.ri b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/emit-i.ri new file mode 100644 index 0000000..cde9dc9 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/emit-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/on-i.ri b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/on-i.ri new file mode 100644 index 0000000..1b7d203 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/on-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/once-i.ri b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/once-i.ri new file mode 100644 index 0000000..b9c8e88 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/once-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/remove_listener-i.ri b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/remove_listener-i.ri new file mode 100644 index 0000000..b825a0e Binary files /dev/null and b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/InstanceMethods/remove_listener-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/apply-c.ri b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/apply-c.ri new file mode 100644 index 0000000..637f5e2 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/apply-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/cdesc-EventEmitter.ri b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/cdesc-EventEmitter.ri new file mode 100644 index 0000000..9491f70 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/cdesc-EventEmitter.ri differ diff --git a/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/included-c.ri b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/included-c.ri new file mode 100644 index 0000000..92b8cc6 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/EventEmitter/included-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/cache.ri b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/cache.ri new file mode 100644 index 0000000..d7beb0c Binary files /dev/null and b/games/FNaFB2/Ruby/doc/event_emitter-0.2.6/ri/cache.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/ControlFramePayloadTooLong/cdesc-ControlFramePayloadTooLong.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/ControlFramePayloadTooLong/cdesc-ControlFramePayloadTooLong.ri new file mode 100644 index 0000000..2b500f4 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/ControlFramePayloadTooLong/cdesc-ControlFramePayloadTooLong.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/ControlFramePayloadTooLong/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/ControlFramePayloadTooLong/message-i.ri new file mode 100644 index 0000000..b32b0c3 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/ControlFramePayloadTooLong/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/DataFrameInsteadContinuation/cdesc-DataFrameInsteadContinuation.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/DataFrameInsteadContinuation/cdesc-DataFrameInsteadContinuation.ri new file mode 100644 index 0000000..42d12d2 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/DataFrameInsteadContinuation/cdesc-DataFrameInsteadContinuation.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/DataFrameInsteadContinuation/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/DataFrameInsteadContinuation/message-i.ri new file mode 100644 index 0000000..ffe873d Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/DataFrameInsteadContinuation/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/FragmentedControlFrame/cdesc-FragmentedControlFrame.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/FragmentedControlFrame/cdesc-FragmentedControlFrame.ri new file mode 100644 index 0000000..243a4d5 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/FragmentedControlFrame/cdesc-FragmentedControlFrame.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/FragmentedControlFrame/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/FragmentedControlFrame/message-i.ri new file mode 100644 index 0000000..02d1892 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/FragmentedControlFrame/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/Invalid/cdesc-Invalid.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/Invalid/cdesc-Invalid.ri new file mode 100644 index 0000000..f4aafab Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/Invalid/cdesc-Invalid.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/Invalid/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/Invalid/message-i.ri new file mode 100644 index 0000000..e5f373a Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/Invalid/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/InvalidPayloadEncoding/cdesc-InvalidPayloadEncoding.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/InvalidPayloadEncoding/cdesc-InvalidPayloadEncoding.ri new file mode 100644 index 0000000..b7b511c Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/InvalidPayloadEncoding/cdesc-InvalidPayloadEncoding.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/InvalidPayloadEncoding/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/InvalidPayloadEncoding/message-i.ri new file mode 100644 index 0000000..5e15051 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/InvalidPayloadEncoding/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/MaskTooShort/cdesc-MaskTooShort.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/MaskTooShort/cdesc-MaskTooShort.ri new file mode 100644 index 0000000..ec7df04 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/MaskTooShort/cdesc-MaskTooShort.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/MaskTooShort/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/MaskTooShort/message-i.ri new file mode 100644 index 0000000..3ad6a87 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/MaskTooShort/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/ReservedBitUsed/cdesc-ReservedBitUsed.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/ReservedBitUsed/cdesc-ReservedBitUsed.ri new file mode 100644 index 0000000..8139573 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/ReservedBitUsed/cdesc-ReservedBitUsed.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/ReservedBitUsed/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/ReservedBitUsed/message-i.ri new file mode 100644 index 0000000..fb1b14b Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/ReservedBitUsed/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/TooLong/cdesc-TooLong.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/TooLong/cdesc-TooLong.ri new file mode 100644 index 0000000..4c1a2c7 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/TooLong/cdesc-TooLong.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/TooLong/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/TooLong/message-i.ri new file mode 100644 index 0000000..526442d Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/TooLong/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnexpectedContinuationFrame/cdesc-UnexpectedContinuationFrame.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnexpectedContinuationFrame/cdesc-UnexpectedContinuationFrame.ri new file mode 100644 index 0000000..c235a07 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnexpectedContinuationFrame/cdesc-UnexpectedContinuationFrame.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnexpectedContinuationFrame/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnexpectedContinuationFrame/message-i.ri new file mode 100644 index 0000000..df946f2 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnexpectedContinuationFrame/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownCloseCode/cdesc-UnknownCloseCode.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownCloseCode/cdesc-UnknownCloseCode.ri new file mode 100644 index 0000000..45c170d Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownCloseCode/cdesc-UnknownCloseCode.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownCloseCode/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownCloseCode/message-i.ri new file mode 100644 index 0000000..4dc8df2 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownCloseCode/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownFrameType/cdesc-UnknownFrameType.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownFrameType/cdesc-UnknownFrameType.ri new file mode 100644 index 0000000..1f9c48c Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownFrameType/cdesc-UnknownFrameType.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownFrameType/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownFrameType/message-i.ri new file mode 100644 index 0000000..57a0f0a Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownFrameType/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownOpcode/cdesc-UnknownOpcode.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownOpcode/cdesc-UnknownOpcode.ri new file mode 100644 index 0000000..65fe218 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownOpcode/cdesc-UnknownOpcode.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownOpcode/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownOpcode/message-i.ri new file mode 100644 index 0000000..6ad3f5f Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownOpcode/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownVersion/cdesc-UnknownVersion.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownVersion/cdesc-UnknownVersion.ri new file mode 100644 index 0000000..c5aef25 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownVersion/cdesc-UnknownVersion.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownVersion/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownVersion/message-i.ri new file mode 100644 index 0000000..9e35030 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/UnknownVersion/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/cdesc-Frame.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/cdesc-Frame.ri new file mode 100644 index 0000000..20d145a Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Frame/cdesc-Frame.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/GetRequestRequired/cdesc-GetRequestRequired.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/GetRequestRequired/cdesc-GetRequestRequired.ri new file mode 100644 index 0000000..b51e88d Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/GetRequestRequired/cdesc-GetRequestRequired.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/GetRequestRequired/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/GetRequestRequired/message-i.ri new file mode 100644 index 0000000..0520200 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/GetRequestRequired/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidAuthentication/cdesc-InvalidAuthentication.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidAuthentication/cdesc-InvalidAuthentication.ri new file mode 100644 index 0000000..711db95 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidAuthentication/cdesc-InvalidAuthentication.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidAuthentication/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidAuthentication/message-i.ri new file mode 100644 index 0000000..e42ca8e Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidAuthentication/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidHeader/cdesc-InvalidHeader.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidHeader/cdesc-InvalidHeader.ri new file mode 100644 index 0000000..dbd442a Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidHeader/cdesc-InvalidHeader.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidHeader/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidHeader/message-i.ri new file mode 100644 index 0000000..092a46a Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidHeader/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidStatusCode/cdesc-InvalidStatusCode.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidStatusCode/cdesc-InvalidStatusCode.ri new file mode 100644 index 0000000..849b25d Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidStatusCode/cdesc-InvalidStatusCode.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidStatusCode/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidStatusCode/message-i.ri new file mode 100644 index 0000000..d1b4f17 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/InvalidStatusCode/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/NoHostProvided/cdesc-NoHostProvided.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/NoHostProvided/cdesc-NoHostProvided.ri new file mode 100644 index 0000000..eb59814 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/NoHostProvided/cdesc-NoHostProvided.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/NoHostProvided/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/NoHostProvided/message-i.ri new file mode 100644 index 0000000..ab97ac5 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/NoHostProvided/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/UnknownVersion/cdesc-UnknownVersion.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/UnknownVersion/cdesc-UnknownVersion.ri new file mode 100644 index 0000000..884d675 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/UnknownVersion/cdesc-UnknownVersion.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/UnknownVersion/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/UnknownVersion/message-i.ri new file mode 100644 index 0000000..1a6a09f Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/UnknownVersion/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/UnsupportedProtocol/cdesc-UnsupportedProtocol.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/UnsupportedProtocol/cdesc-UnsupportedProtocol.ri new file mode 100644 index 0000000..9fe4f56 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/UnsupportedProtocol/cdesc-UnsupportedProtocol.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/UnsupportedProtocol/message-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/UnsupportedProtocol/message-i.ri new file mode 100644 index 0000000..667d67b Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/UnsupportedProtocol/message-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/cdesc-Handshake.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/cdesc-Handshake.ri new file mode 100644 index 0000000..3be7a8b Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/Handshake/cdesc-Handshake.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/cdesc-Error.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/cdesc-Error.ri new file mode 100644 index 0000000..002b069 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Error/cdesc-Error.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/ClassMethods/cdesc-ClassMethods.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/ClassMethods/cdesc-ClassMethods.ri new file mode 100644 index 0000000..889326c Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/ClassMethods/cdesc-ClassMethods.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/ClassMethods/rescue_method-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/ClassMethods/rescue_method-i.ri new file mode 100644 index 0000000..40e6a38 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/ClassMethods/rescue_method-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/cdesc-ExceptionHandler.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/cdesc-ExceptionHandler.ri new file mode 100644 index 0000000..bb4a581 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/cdesc-ExceptionHandler.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/error-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/error-i.ri new file mode 100644 index 0000000..d5540b2 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/error-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/included-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/included-c.ri new file mode 100644 index 0000000..10b9242 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/ExceptionHandler/included-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/cdesc-Base.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/cdesc-Base.ri new file mode 100644 index 0000000..a868f5c Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/cdesc-Base.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/code-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/code-i.ri new file mode 100644 index 0000000..39f8a74 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/code-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/data-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/data-i.ri new file mode 100644 index 0000000..28118dc Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/data-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/error%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/error%3f-i.ri new file mode 100644 index 0000000..ef38604 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/error%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/error-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/error-i.ri new file mode 100644 index 0000000..cf29504 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/error-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/include_version-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/include_version-i.ri new file mode 100644 index 0000000..f0d0793 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/include_version-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/new-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/new-c.ri new file mode 100644 index 0000000..e77cd72 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/new-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/support_type%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/support_type%3f-i.ri new file mode 100644 index 0000000..7a48d36 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/support_type%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/supported_frames-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/supported_frames-i.ri new file mode 100644 index 0000000..b456049 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/supported_frames-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/type-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/type-i.ri new file mode 100644 index 0000000..4b79995 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/type-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/version-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/version-i.ri new file mode 100644 index 0000000..2323dcf Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Base/version-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/%3c%3c-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/%3c%3c-i.ri new file mode 100644 index 0000000..a9cd986 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/%3c%3c-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/cdesc-Data.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/cdesc-Data.ri new file mode 100644 index 0000000..db09f75 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/cdesc-Data.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/convert_args-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/convert_args-i.ri new file mode 100644 index 0000000..713f54d Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/convert_args-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/getbytes-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/getbytes-i.ri new file mode 100644 index 0000000..0a854ca Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/getbytes-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/mask-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/mask-i.ri new file mode 100644 index 0000000..643657f Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/mask-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/new-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/new-c.ri new file mode 100644 index 0000000..b7dfcbc Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/new-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/set_mask-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/set_mask-i.ri new file mode 100644 index 0000000..93b6cd8 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/set_mask-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/unset_mask-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/unset_mask-i.ri new file mode 100644 index 0000000..7fab66a Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Data/unset_mask-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/cdesc-Base.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/cdesc-Base.ri new file mode 100644 index 0000000..a34a695 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/cdesc-Base.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/control_frame%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/control_frame%3f-i.ri new file mode 100644 index 0000000..3793136 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/control_frame%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/data_frame%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/data_frame%3f-i.ri new file mode 100644 index 0000000..343edcf Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/data_frame%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/decode_frame-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/decode_frame-i.ri new file mode 100644 index 0000000..34ad672 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/decode_frame-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/encode_frame-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/encode_frame-i.ri new file mode 100644 index 0000000..f198da2 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/encode_frame-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/new-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/new-c.ri new file mode 100644 index 0000000..9ce5f48 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Base/new-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/buffer_exists%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/buffer_exists%3f-i.ri new file mode 100644 index 0000000..57d713a Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/buffer_exists%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/cdesc-Handler03.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/cdesc-Handler03.ri new file mode 100644 index 0000000..dab5788 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/cdesc-Handler03.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_continuation_frame-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_continuation_frame-i.ri new file mode 100644 index 0000000..2e26047 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_continuation_frame-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_finish_continuation_frame-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_finish_continuation_frame-i.ri new file mode 100644 index 0000000..d1fa437 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_finish_continuation_frame-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_first_byte-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_first_byte-i.ri new file mode 100644 index 0000000..57fb6a7 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_first_byte-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_frame-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_frame-i.ri new file mode 100644 index 0000000..70c4c55 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_frame-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_header-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_header-i.ri new file mode 100644 index 0000000..8e6d189 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_header-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_payload-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_payload-i.ri new file mode 100644 index 0000000..62ac4c9 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_payload-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_payload_length-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_payload_length-i.ri new file mode 100644 index 0000000..18fc0cb Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_payload_length-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_second_byte-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_second_byte-i.ri new file mode 100644 index 0000000..43f6109 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/decode_second_byte-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/encode_frame-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/encode_frame-i.ri new file mode 100644 index 0000000..43bc99b Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/encode_frame-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/encode_header-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/encode_header-i.ri new file mode 100644 index 0000000..d6c951b Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/encode_header-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/encode_payload_length-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/encode_payload_length-i.ri new file mode 100644 index 0000000..0e89302 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/encode_payload_length-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/fin-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/fin-i.ri new file mode 100644 index 0000000..e40e0a1 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/fin-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/masking%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/masking%3f-i.ri new file mode 100644 index 0000000..9911054 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/masking%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/new-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/new-c.ri new file mode 100644 index 0000000..7915b57 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/new-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/opcode_to_type-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/opcode_to_type-i.ri new file mode 100644 index 0000000..65a49ca Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/opcode_to_type-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/supported_frames-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/supported_frames-i.ri new file mode 100644 index 0000000..09f62ca Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/supported_frames-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/type_to_opcode-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/type_to_opcode-i.ri new file mode 100644 index 0000000..7bbcac2 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler03/type_to_opcode-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler04/cdesc-Handler04.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler04/cdesc-Handler04.ri new file mode 100644 index 0000000..c1aed8b Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler04/cdesc-Handler04.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler04/fin-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler04/fin-i.ri new file mode 100644 index 0000000..3129da4 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler04/fin-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler05/cdesc-Handler05.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler05/cdesc-Handler05.ri new file mode 100644 index 0000000..69bb103 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler05/cdesc-Handler05.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler05/masking%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler05/masking%3f-i.ri new file mode 100644 index 0000000..0729c39 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler05/masking%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/cdesc-Handler07.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/cdesc-Handler07.ri new file mode 100644 index 0000000..612ca30 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/cdesc-Handler07.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/close_code%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/close_code%3f-i.ri new file mode 100644 index 0000000..7859219 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/close_code%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/decode_frame-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/decode_frame-i.ri new file mode 100644 index 0000000..c8f3e13 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/decode_frame-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/encode_frame-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/encode_frame-i.ri new file mode 100644 index 0000000..3bcadfa Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/encode_frame-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/opcode_to_type-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/opcode_to_type-i.ri new file mode 100644 index 0000000..416f7e1 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/opcode_to_type-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/type_to_opcode-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/type_to_opcode-i.ri new file mode 100644 index 0000000..81ee9ec Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/type_to_opcode-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/valid_code%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/valid_code%3f-i.ri new file mode 100644 index 0000000..ae069ba Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/valid_code%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/valid_encoding%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/valid_encoding%3f-i.ri new file mode 100644 index 0000000..ed0cc6a Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler07/valid_encoding%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler75/cdesc-Handler75.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler75/cdesc-Handler75.ri new file mode 100644 index 0000000..9a04a0e Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler75/cdesc-Handler75.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler75/decode_frame-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler75/decode_frame-i.ri new file mode 100644 index 0000000..f1c7011 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler75/decode_frame-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler75/encode_frame-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler75/encode_frame-i.ri new file mode 100644 index 0000000..571fee1 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler75/encode_frame-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler75/supported_frames-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler75/supported_frames-i.ri new file mode 100644 index 0000000..b435e2f Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/Handler75/supported_frames-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/cdesc-Handler.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/cdesc-Handler.ri new file mode 100644 index 0000000..68498f8 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Handler/cdesc-Handler.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/%3c%3c-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/%3c%3c-i.ri new file mode 100644 index 0000000..861c1ea Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/%3c%3c-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Client/cdesc-Client.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Client/cdesc-Client.ri new file mode 100644 index 0000000..5f53bca Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Client/cdesc-Client.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Client/incoming_masking%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Client/incoming_masking%3f-i.ri new file mode 100644 index 0000000..3dcfb04 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Client/incoming_masking%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Client/outgoing_masking%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Client/outgoing_masking%3f-i.ri new file mode 100644 index 0000000..ae714a2 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Client/outgoing_masking%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Server/cdesc-Server.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Server/cdesc-Server.ri new file mode 100644 index 0000000..100a2ec Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Server/cdesc-Server.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Server/incoming_masking%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Server/incoming_masking%3f-i.ri new file mode 100644 index 0000000..37caa51 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Server/incoming_masking%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Server/outgoing_masking%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Server/outgoing_masking%3f-i.ri new file mode 100644 index 0000000..34890ce Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/Server/outgoing_masking%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/cdesc-Incoming.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/cdesc-Incoming.ri new file mode 100644 index 0000000..c723855 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/cdesc-Incoming.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/decoded%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/decoded%3f-i.ri new file mode 100644 index 0000000..7b5eead Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/decoded%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/new-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/new-c.ri new file mode 100644 index 0000000..a9fe777 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/new-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/next-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/next-i.ri new file mode 100644 index 0000000..a5a1aff Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/next-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/to_s-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/to_s-i.ri new file mode 100644 index 0000000..0ae0be7 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Incoming/to_s-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Client/cdesc-Client.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Client/cdesc-Client.ri new file mode 100644 index 0000000..7fe963c Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Client/cdesc-Client.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Client/incoming_masking%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Client/incoming_masking%3f-i.ri new file mode 100644 index 0000000..b0b669f Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Client/incoming_masking%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Client/outgoing_masking%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Client/outgoing_masking%3f-i.ri new file mode 100644 index 0000000..6ee4bff Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Client/outgoing_masking%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Server/cdesc-Server.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Server/cdesc-Server.ri new file mode 100644 index 0000000..5d9983f Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Server/cdesc-Server.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Server/incoming_masking%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Server/incoming_masking%3f-i.ri new file mode 100644 index 0000000..0094498 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Server/incoming_masking%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Server/outgoing_masking%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Server/outgoing_masking%3f-i.ri new file mode 100644 index 0000000..c118614 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/Server/outgoing_masking%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/cdesc-Outgoing.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/cdesc-Outgoing.ri new file mode 100644 index 0000000..88fd479 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/cdesc-Outgoing.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/require_sending%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/require_sending%3f-i.ri new file mode 100644 index 0000000..23febe9 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/require_sending%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/supported%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/supported%3f-i.ri new file mode 100644 index 0000000..92653d4 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/supported%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/to_s-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/to_s-i.ri new file mode 100644 index 0000000..2fce8aa Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/Outgoing/to_s-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/cdesc-Frame.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/cdesc-Frame.ri new file mode 100644 index 0000000..86e0368 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Frame/cdesc-Frame.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/%3c%3c-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/%3c%3c-i.ri new file mode 100644 index 0000000..0c5814f Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/%3c%3c-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/cdesc-Base.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/cdesc-Base.ri new file mode 100644 index 0000000..d484d3e Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/cdesc-Base.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/default_port%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/default_port%3f-i.ri new file mode 100644 index 0000000..9fa3411 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/default_port%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/default_port-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/default_port-i.ri new file mode 100644 index 0000000..1ee4eb1 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/default_port-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/error%3d-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/error%3d-i.ri new file mode 100644 index 0000000..a2f553a Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/error%3d-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/finished%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/finished%3f-i.ri new file mode 100644 index 0000000..79ead88 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/finished%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/headers-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/headers-i.ri new file mode 100644 index 0000000..c79d456 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/headers-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/host-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/host-i.ri new file mode 100644 index 0000000..55bcc10 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/host-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/leftovers-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/leftovers-i.ri new file mode 100644 index 0000000..9cad63b Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/leftovers-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/new-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/new-c.ri new file mode 100644 index 0000000..127db95 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/new-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/parse_data-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/parse_data-i.ri new file mode 100644 index 0000000..90f6026 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/parse_data-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/path-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/path-i.ri new file mode 100644 index 0000000..ebdf3b4 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/path-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/port-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/port-i.ri new file mode 100644 index 0000000..0825a9e Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/port-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/protocols-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/protocols-i.ri new file mode 100644 index 0000000..192de31 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/protocols-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/query-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/query-i.ri new file mode 100644 index 0000000..97417aa Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/query-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/reserved_leftover_lines-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/reserved_leftover_lines-i.ri new file mode 100644 index 0000000..49c9563 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/reserved_leftover_lines-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/secure-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/secure-i.ri new file mode 100644 index 0000000..1f27003 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/secure-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/should_respond%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/should_respond%3f-i.ri new file mode 100644 index 0000000..f9261fd Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/should_respond%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/state-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/state-i.ri new file mode 100644 index 0000000..577df45 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/state-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/to_s-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/to_s-i.ri new file mode 100644 index 0000000..d086356 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/to_s-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/uri-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/uri-i.ri new file mode 100644 index 0000000..a327458 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/uri-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/valid%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/valid%3f-i.ri new file mode 100644 index 0000000..4bdcdea Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/valid%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/version-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/version-i.ri new file mode 100644 index 0000000..5e6b5bc Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Base/version-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/%3c%3c-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/%3c%3c-i.ri new file mode 100644 index 0000000..5663f08 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/%3c%3c-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/cdesc-Client.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/cdesc-Client.ri new file mode 100644 index 0000000..b9441d3 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/cdesc-Client.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/headers-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/headers-i.ri new file mode 100644 index 0000000..890bb41 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/headers-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/include_version-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/include_version-i.ri new file mode 100644 index 0000000..7ecc7d8 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/include_version-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/new-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/new-c.ri new file mode 100644 index 0000000..a057742 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/new-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/origin-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/origin-i.ri new file mode 100644 index 0000000..0be5761 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/origin-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/parse_first_line-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/parse_first_line-i.ri new file mode 100644 index 0000000..b533bc8 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/parse_first_line-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/should_respond%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/should_respond%3f-i.ri new file mode 100644 index 0000000..ef3af21 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Client/should_respond%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/cdesc-Base.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/cdesc-Base.ri new file mode 100644 index 0000000..facf9c0 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/cdesc-Base.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/finishing_line-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/finishing_line-i.ri new file mode 100644 index 0000000..6d0a771 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/finishing_line-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/handshake_keys-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/handshake_keys-i.ri new file mode 100644 index 0000000..b514fd5 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/handshake_keys-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/header_line-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/header_line-i.ri new file mode 100644 index 0000000..42cc40b Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/header_line-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/new-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/new-c.ri new file mode 100644 index 0000000..b0c11a4 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/new-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/to_s-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/to_s-i.ri new file mode 100644 index 0000000..46473f0 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/to_s-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/valid%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/valid%3f-i.ri new file mode 100644 index 0000000..9fe842f Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Base/valid%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client/cdesc-Client.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client/cdesc-Client.ri new file mode 100644 index 0000000..e8a52aa Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client/cdesc-Client.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client/handshake_keys-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client/handshake_keys-i.ri new file mode 100644 index 0000000..88ee63d Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client/handshake_keys-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client/header_line-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client/header_line-i.ri new file mode 100644 index 0000000..9fdf43e Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client/header_line-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client/verify_protocol-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client/verify_protocol-i.ri new file mode 100644 index 0000000..58a3a36 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client/verify_protocol-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client01/cdesc-Client01.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client01/cdesc-Client01.ri new file mode 100644 index 0000000..dce6460 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client01/cdesc-Client01.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client01/handshake_keys-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client01/handshake_keys-i.ri new file mode 100644 index 0000000..90d5dc3 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client01/handshake_keys-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/accept-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/accept-i.ri new file mode 100644 index 0000000..2174d65 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/accept-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/cdesc-Client04.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/cdesc-Client04.ri new file mode 100644 index 0000000..b34ac71 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/cdesc-Client04.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/handshake_keys-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/handshake_keys-i.ri new file mode 100644 index 0000000..fdea5cf Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/handshake_keys-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/key-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/key-i.ri new file mode 100644 index 0000000..92143db Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/key-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/provided_protocols-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/provided_protocols-i.ri new file mode 100644 index 0000000..0fb8ef4 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/provided_protocols-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/supported_protocols-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/supported_protocols-i.ri new file mode 100644 index 0000000..d6966cd Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/supported_protocols-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/valid%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/valid%3f-i.ri new file mode 100644 index 0000000..3c10342 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/valid%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/verify_accept-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/verify_accept-i.ri new file mode 100644 index 0000000..fe330e1 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client04/verify_accept-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client11/cdesc-Client11.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client11/cdesc-Client11.ri new file mode 100644 index 0000000..d857346 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client11/cdesc-Client11.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client11/handshake_keys-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client11/handshake_keys-i.ri new file mode 100644 index 0000000..e771eae Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client11/handshake_keys-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/cdesc-Client75.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/cdesc-Client75.ri new file mode 100644 index 0000000..e924408 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/cdesc-Client75.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/handshake_keys-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/handshake_keys-i.ri new file mode 100644 index 0000000..1f327f0 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/handshake_keys-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/provided_protocols-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/provided_protocols-i.ri new file mode 100644 index 0000000..9788e7b Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/provided_protocols-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/supported_protocols-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/supported_protocols-i.ri new file mode 100644 index 0000000..1cfcbca Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/supported_protocols-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/valid%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/valid%3f-i.ri new file mode 100644 index 0000000..4ebc42c Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client75/valid%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/cdesc-Client76.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/cdesc-Client76.ri new file mode 100644 index 0000000..8c38656 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/cdesc-Client76.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/challenge-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/challenge-i.ri new file mode 100644 index 0000000..32b8e46 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/challenge-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/finishing_line-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/finishing_line-i.ri new file mode 100644 index 0000000..3c58a9e Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/finishing_line-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/generate_key-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/generate_key-i.ri new file mode 100644 index 0000000..0be71ca Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/generate_key-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/generate_key3-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/generate_key3-i.ri new file mode 100644 index 0000000..65b5a73 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/generate_key3-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/handshake_keys-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/handshake_keys-i.ri new file mode 100644 index 0000000..cc51718 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/handshake_keys-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/key1-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/key1-i.ri new file mode 100644 index 0000000..e2e8704 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/key1-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/key2-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/key2-i.ri new file mode 100644 index 0000000..ebfd4d4 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/key2-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/key3-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/key3-i.ri new file mode 100644 index 0000000..8e2be9d Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/key3-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/provided_protocols-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/provided_protocols-i.ri new file mode 100644 index 0000000..34376e7 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/provided_protocols-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/reserved_leftover_lines-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/reserved_leftover_lines-i.ri new file mode 100644 index 0000000..74f1ff9 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/reserved_leftover_lines-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/valid%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/valid%3f-i.ri new file mode 100644 index 0000000..b75a4ec Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/valid%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/verify_challenge-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/verify_challenge-i.ri new file mode 100644 index 0000000..058a05a Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Client76/verify_challenge-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server/cdesc-Server.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server/cdesc-Server.ri new file mode 100644 index 0000000..868f932 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server/cdesc-Server.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/cdesc-Server04.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/cdesc-Server04.ri new file mode 100644 index 0000000..0a9f2dc Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/cdesc-Server04.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/handshake_keys-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/handshake_keys-i.ri new file mode 100644 index 0000000..35ff823 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/handshake_keys-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/header_line-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/header_line-i.ri new file mode 100644 index 0000000..9927e0f Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/header_line-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/key-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/key-i.ri new file mode 100644 index 0000000..6160ea3 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/key-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/protocol-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/protocol-i.ri new file mode 100644 index 0000000..0526d5d Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/protocol-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/signature-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/signature-i.ri new file mode 100644 index 0000000..6271cfa Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/signature-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/valid%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/valid%3f-i.ri new file mode 100644 index 0000000..08c4931 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/valid%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/verify_key-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/verify_key-i.ri new file mode 100644 index 0000000..3c7591f Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server04/verify_key-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/cdesc-Server75.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/cdesc-Server75.ri new file mode 100644 index 0000000..159c58a Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/cdesc-Server75.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/handshake_keys-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/handshake_keys-i.ri new file mode 100644 index 0000000..eceb739 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/handshake_keys-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/header_line-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/header_line-i.ri new file mode 100644 index 0000000..64fa23f Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/header_line-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/headers-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/headers-i.ri new file mode 100644 index 0000000..1591c25 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/headers-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/protocol-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/protocol-i.ri new file mode 100644 index 0000000..f64e4b3 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server75/protocol-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/cdesc-Server76.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/cdesc-Server76.ri new file mode 100644 index 0000000..903ef91 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/cdesc-Server76.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/challenge_response-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/challenge_response-i.ri new file mode 100644 index 0000000..8fc2129 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/challenge_response-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/finishing_line-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/finishing_line-i.ri new file mode 100644 index 0000000..e7e0466 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/finishing_line-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/header_line-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/header_line-i.ri new file mode 100644 index 0000000..945bcca Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/header_line-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/headers-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/headers-i.ri new file mode 100644 index 0000000..5fd4ef4 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/headers-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/numbers_over_spaces-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/numbers_over_spaces-i.ri new file mode 100644 index 0000000..d85bcfd Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/numbers_over_spaces-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/reserved_leftover_lines-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/reserved_leftover_lines-i.ri new file mode 100644 index 0000000..b134c43 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/reserved_leftover_lines-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/valid%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/valid%3f-i.ri new file mode 100644 index 0000000..d22e945 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/Server76/valid%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/cdesc-Handler.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/cdesc-Handler.ri new file mode 100644 index 0000000..3e54cc7 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Handler/cdesc-Handler.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/%3c%3c-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/%3c%3c-i.ri new file mode 100644 index 0000000..3ca5957 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/%3c%3c-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/cdesc-Server.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/cdesc-Server.ri new file mode 100644 index 0000000..3738e23 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/cdesc-Server.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/from_hash-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/from_hash-i.ri new file mode 100644 index 0000000..9283a62 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/from_hash-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/from_rack-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/from_rack-i.ri new file mode 100644 index 0000000..65bcc4a Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/from_rack-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/host-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/host-i.ri new file mode 100644 index 0000000..e05f54e Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/host-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/include_version-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/include_version-i.ri new file mode 100644 index 0000000..b740824 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/include_version-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/new-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/new-c.ri new file mode 100644 index 0000000..b5cc667 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/new-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/parse_first_line-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/parse_first_line-i.ri new file mode 100644 index 0000000..1701397 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/parse_first_line-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/port-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/port-i.ri new file mode 100644 index 0000000..269f450 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/port-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/set_version-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/set_version-i.ri new file mode 100644 index 0000000..f7fffb8 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/set_version-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/should_respond%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/should_respond%3f-i.ri new file mode 100644 index 0000000..2932f4e Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/Server/should_respond%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/cdesc-Handshake.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/cdesc-Handshake.ri new file mode 100644 index 0000000..6c252bb Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/Handshake/cdesc-Handshake.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/NiceInspect/cdesc-NiceInspect.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/NiceInspect/cdesc-NiceInspect.ri new file mode 100644 index 0000000..3c0b8b7 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/NiceInspect/cdesc-NiceInspect.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/NiceInspect/inspect-i.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/NiceInspect/inspect-i.ri new file mode 100644 index 0000000..65f1534 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/NiceInspect/inspect-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/cdesc-WebSocket.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/cdesc-WebSocket.ri new file mode 100644 index 0000000..8a6506d Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/cdesc-WebSocket.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/max_frame_size%3d-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/max_frame_size%3d-c.ri new file mode 100644 index 0000000..6f14a90 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/max_frame_size%3d-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/max_frame_size-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/max_frame_size-c.ri new file mode 100644 index 0000000..6a9bafa Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/max_frame_size-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/should_raise%3d-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/should_raise%3d-c.ri new file mode 100644 index 0000000..be78a06 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/should_raise%3d-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/should_raise-c.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/should_raise-c.ri new file mode 100644 index 0000000..adadbb2 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/WebSocket/should_raise-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/cache.ri b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/cache.ri new file mode 100644 index 0000000..f19fca1 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-1.2.10/ri/cache.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/cdesc-Client.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/cdesc-Client.ri new file mode 100644 index 0000000..42cdd36 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/cdesc-Client.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/close-i.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/close-i.ri new file mode 100644 index 0000000..1345670 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/close-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/closed%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/closed%3f-i.ri new file mode 100644 index 0000000..cd6edf0 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/closed%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/connect-i.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/connect-i.ri new file mode 100644 index 0000000..a59e7e6 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/connect-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/handshake-i.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/handshake-i.ri new file mode 100644 index 0000000..25cd60f Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/handshake-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/open%3f-i.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/open%3f-i.ri new file mode 100644 index 0000000..bfac5bf Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/open%3f-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/send-i.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/send-i.ri new file mode 100644 index 0000000..4f88513 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/send-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/thread-i.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/thread-i.ri new file mode 100644 index 0000000..8e7a786 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/thread-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/url-i.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/url-i.ri new file mode 100644 index 0000000..dee068c Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/Client/url-i.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/cdesc-Simple.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/cdesc-Simple.ri new file mode 100644 index 0000000..9b35998 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/cdesc-Simple.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/connect-c.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/connect-c.ri new file mode 100644 index 0000000..f91c7d8 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/Simple/connect-c.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/cdesc-Client.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/cdesc-Client.ri new file mode 100644 index 0000000..14326a7 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/Client/cdesc-Client.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/cdesc-WebSocket.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/cdesc-WebSocket.ri new file mode 100644 index 0000000..0af3b79 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/WebSocket/cdesc-WebSocket.ri differ diff --git a/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/cache.ri b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/cache.ri new file mode 100644 index 0000000..352b317 Binary files /dev/null and b/games/FNaFB2/Ruby/doc/websocket-client-simple-0.8.0/ri/cache.ri differ diff --git a/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb.rb b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb.rb new file mode 100644 index 0000000..896fc99 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb.rb @@ -0,0 +1 @@ +require_relative 'archipelago_rb/client' \ No newline at end of file diff --git a/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/client.rb b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/client.rb new file mode 100644 index 0000000..2b663a3 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/client.rb @@ -0,0 +1,199 @@ +require_relative 'packets' +require_relative 'constants' +require_relative 'objects' +require_relative 'locations' +require_relative 'data' +require_relative 'items' +require_relative 'players' +require_relative 'hints' +require 'websocket-client-simple' +require 'json' + +module Archipelago + + class Client + attr_accessor :connect_info + attr_reader :data, :locations, :items, :players, :hints, :client_connect_status, :client_socket + + def initialize() + @connect_info = {} + @terminate = false + @client_version = Objects::Version.new(0, 5, 0) + @client_connect_status = ConnectStatus::DISCONNECTED + @data = Data.new() + @locations = Locations.new(self) + @items = Items.new(self) + @players = Players.new(self) + @hints = Hints.new(self) + @listeners = Hash.new { |hash, key| hash[key] = []} + + add_default_listeners() + end + + def connect + return if @client_connect_status != ConnectStatus::DISCONNECTED + @terminate = false + Thread.new do + begin + url = "wss://#{@connect_info["hostname"]}:#{@connect_info["port"]}" + @client_socket = WebSocket::Client::Simple.connect(url) + rescue + url = "ws://#{@connect_info["hostname"]}:#{@connect_info["port"]}" + @client_socket = WebSocket::Client::Simple.connect(url) + end + + @client_socket.on :open do + end + + packet_handler = method(:notify_listeners) + + @client_socket.on :message do |msg| + packet_handler.call(msg) + end + + @client_socket.on :error do |e| + puts "-- error (#{e.inspect})" + end + + @client_socket.on :close do + end + + loop do + sleep 1 + break if @terminate + end + end + + end + + def disconnect + if @client_socket + @client_socket.close + @terminate = true + @client_connect_status = ConnectStatus::DISCONNECTED + puts "Client disconnected." + end + end + + def add_listener(packet_type, &block) + @listeners[packet_type] << block + end + + def say(text) + if @client_connect_status == ConnectStatus::CONNECTED + say_packet = Packets::Say.new(text) + @client_socket.send(say_packet.to_json) + else + puts "[Client say] You need to have an active Archipelago connection to use this!" + end + end + + def update_status(status) + if @client_connect_status == ConnectStatus::CONNECTED + status_packet = Packets::StatusUpdate.new(status) + @client_socket.send(status_packet.to_json) + else + puts "[Client update_status] You need to have an active Archipelago connection to use this!" + end + end + + private + + def notify_listeners(msg) + if valid_json?(msg.data) + datapackets = JSON.parse(msg.data) + datapackets.each do |packet| + @listeners[packet["cmd"]].each { |listener| listener.call(packet)} + end + elsif msg.type == :ping + @client_socket.send(msg.data, type: :pong) + else + puts msg + end + end + + def add_default_listeners + + add_listener("RoomInfo") do |msg| + @data.import_game_data(msg) + + password = nil + if @data.game_data["password"] and @connect_info["password"].empty? + puts "Password:" + password = STDIN.gets.strip + elsif @data.game_data["password"] + password = @connect_info["password"] + end + + connect_packet = Packets::Connect.new( + password, + @connect_info["game"], + @connect_info["name"], + "99999", + @client_version.to_hash, + @connect_info["items_handling"], + ["AP"], true + ) + + @client_socket.send(connect_packet.to_json) + end + + add_listener("Connected") do |msg| + @data.import_game_data(msg) + + @locations.import_checked_locations(@data.game_data["checked_locations"]) + @locations.import_missing_locations(@data.game_data["missing_locations"]) + + datapackages_to_update = @data.import_datapackages + if !datapackages_to_update.empty? + getDataPackagePacket = Packets::GetDataPackage.new(datapackages_to_update) + @client_socket.send(getDataPackagePacket.to_json) + end + + @locations.import_datapackages(@data.datapackages) + @items.import_datapackages(@data.datapackages) + @client_connect_status = ConnectStatus::CONNECTED + puts "Connection successful!" + end + + add_listener("RoomUpdate") do |msg| + @data.import_game_data(msg) + end + + add_listener("ReceivedItems") do |msg| + msg["items"].each do |item| + @items.received << item + end + end + + add_listener("ConnectionRefused") do |msg| + puts connectionrefused_packet["errors"] + end + + add_listener("PrintJSON") do |msg| + message = "" + msg["data"].each do |data| + case data["type"] + when "player_id" + message << @data.slot_info[data["text"]]["name"] + when "item_id" + id = data["player"].to_s + message << @items.name(@data.slot_info[id]["game"], data["text"].to_i) + when "location_id" + id = data["player"].to_s + message << @locations.name(@data.slot_info[id]["game"], data["text"].to_i) + else + message << data["text"] + end + end + puts message + end + + add_listener("DataPackage") do |msg| + @data.update_datapackages(msg) + @locations.import_datapackages(@data.datapackages) + @items.import_datapackages(@data.datapackages) + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/constants.rb b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/constants.rb new file mode 100644 index 0000000..0a692e6 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/constants.rb @@ -0,0 +1,53 @@ +module Archipelago + + # ---------------------------------- + # CONSTANTS + # These structures are just referred to for convenience. + # ---------------------------------- + + # ConnectStatus - The client's connection status to the multiworld. + module ConnectStatus + DISCONNECTED = 0 + CONNECTING = 1 + CONNECTED = 2 + end + + # ItemsHandlingFlags - What items should be recieved by the multiworld? + module ItemsHandlingFlags + LOCAL_ONLY = 0b000 # Never get any items sent to you. + REMOTE_DIFFERENT_WORLDS = 0b001 # Get items sent to you from other worlds. + REMOTE_OWN_WORLD = 0b010 # Get items sent to you from your own world. Requires FROM_OTHER to be set. + REMOTE_STARTING_INVENTORY = 0b100 # Get items from your starting inventory. Requires FROM_OTHER to be set. + REMOTE_ALL = 0b111 # Shortcut for FROM_OTHER, FROM_OWN and FROM_STARTING all at once. + end + + # ClientStatus - What is the state of your client? As seen from the server. + module ClientStatus + CLIENT_UNKNOWN = 0 # Who knows? + CLIENT_CONNECTED = 5 # Client connected but is preparing. + CLIENT_READY = 10 # Client is ready to play. + CLIENT_PLAYING = 20 # Client is currently playing. + CLIENT_GOAL = 30 # Client has reached its goal. + end + + module SlotType + SPECTATOR = 0b00 + PLAYER = 0b01 + GROUP = 0b10 + end + + module Permission + DISABLED = 0b000 + ENABLED = 0b001 + GOAL = 0b010 + AUTO = 0b110 + AUTO_ENABLED = 0b111 + end + + module CreateAsHintMode + NO_HINT = 0 + HINT_EVERYTHING = 1 + HINT_ONLY_NEW = 2 + end + +end \ No newline at end of file diff --git a/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/data.rb b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/data.rb new file mode 100644 index 0000000..d2687b1 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/data.rb @@ -0,0 +1,115 @@ +require 'rbconfig' +require 'fileutils' + +module Archipelago + + class Client + + class Data + attr_reader :game_data, :datapackages + + # The DataManager handles data about the current game state. It also imports DataPackages from your local filesystem (or writes should they not exist.) + + def initialize + @data_folder = setup_data_folder() + @game_data = {} + @datapackages = {} + end + + def import_game_data(game_data) + if !["RoomInfo", "Connected", "RoomUpdate"].include?(game_data["cmd"]) + puts "[DataManager import_game_data] Attempted to import #{datapackage["cmd"]}. Expecting RoomInfo, Connected or RoomUpdate." + return + end + game_data.each do |key, value| + @game_data[key] = value + end + @game_data["cmd"] = "Internal Game Data" + end + + def import_datapackages + datapackages_to_update = [] + + @game_data["datapackage_checksums"].each do |game, checksum| + if !Dir.exist?(File.join(@data_folder, game)) + Dir.mkdir(File.join(@data_folder, game)) + datapackages_to_update << game + elsif !File.exist?(File.join(@data_folder, game, "#{checksum}.json")) + datapackages_to_update << game + else + @datapackages[game] = JSON.parse(File.read(File.join(@data_folder, game, "#{checksum}.json")).sub("\xEF\xBB\xBF".force_encoding("UTF-8"), '')) + end + end + + return datapackages_to_update + end + + def update_datapackages(datapackage) + datapackage["data"]["games"].each do |game, datapak| + json_filepath = File.join(@data_folder, game, "#{datapak["checksum"]}.json") + File.delete(json_filepath) if File.exist?(json_filepath) + File.open(json_filepath, 'w') do |file| + file.puts datapak.to_json + @datapackages[game] = datapak + end + end + end + + def slotData + return @game_data["slot_data"] + end + + def method_missing(method_name) + return @game_data[method_name.to_s] + end + + # TODO: The location_names_from_group function. I cannot find any examples of games with groups. + # TODO: Other data functions from archipelago.js + + private + + module OS + WINDOWS = 1 + MACOS = 2 + LINUX = 3 + OTHER = 0 + end + + def get_operating_system + + if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/ + return OS::WINDOWS + elsif RbConfig::CONFIG['host_os'] =~ /darwin/ + return OS::MACOS + elsif RbConfig::CONFIG['host_os'] =~ /linux/ + return OS::LINUX + else + return OS::OTHER + end + + end + + def setup_data_folder + + operating_system = get_operating_system() + appdata_folder = File.join(ENV['LOCALAPPDATA'], "Archipelago") + portable_folder = File.join(".", "Archipelago") + + if Dir.exist?(appdata_folder) && operating_system == OS::WINDOWS + data_folder = File.join(appdata_folder, "Cache", "datapackage") + elsif operating_system == OS::WINDOWS + FileUtils.mkdir_p(File.join(appdata_folder, "Cache", "datapackage")) + data_folder = File.join(appdata_folder, "Cache", "datapackage") + elsif Dir.exist?(portable_folder) + data_folder = File.join(portable_folder, "Cache", "datapackage") + else + FileUtils.mkdir_p(File.join(portable_folder, "Cache", "datapackage")) + data_folder = File.join(portable_folder, "Cache", "datapackage") + end + + return data_folder + + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/hints.rb b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/hints.rb new file mode 100644 index 0000000..60554cd --- /dev/null +++ b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/hints.rb @@ -0,0 +1,17 @@ +module Archipelago + + class Client + + class Hints + + def initialize(client) + @client = client + end + + def mine + #TODO: Add this. I'm not even sure how this'd work. + puts "[HintsManager mine] Hi! This feature isn't implemented yet because I've never used it, so I don't exactly know how. Please hang tight, I'll get it done." + end + end + end +end \ No newline at end of file diff --git a/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/items.rb b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/items.rb new file mode 100644 index 0000000..2157645 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/items.rb @@ -0,0 +1,50 @@ +module Archipelago + + class Client + + class Items + attr_accessor :received, :index + + def initialize(client) + @client = client + @datapackages = {} + @received = [] + @index = 0 + end + + def import_datapackages(datapackages) + @datapackages = datapackages if datapackages.is_a?(Hash) + puts "[ItemsManager import_datapackages] Arg is a #{received_items.class}. Expecting Hash." unless datapackages.is_a?(Hash) + end + + def import_received_items(received_items) + @received = received_items if received_items.is_a?(Array) + puts "[ItemsManager import_received_items] Arg is a #{received_items.class}. Expecting Array." unless received_items.is_a?(Array) + end + + def import_check_index(check_index) + @index = check_index if check_index.is_a?(Integer) + puts "[ItemsManager import_check_index] Check index must be an integer!" unless check_index.is_a?(Integer) + end + + def name(game_name, id) + @datapackages[game_name]["item_name_to_id"].each do |item, value| + return item if value == id + end + return "Unknown Item" + end + + def id(game_name, item_name) + return @datapackages[game_name]["item_name_to_id"][item_name] + rescue + return "Unknown Item" + end + + def group(game_name, group_name) + return @datapackages[game_name]["item_name_groups"][group_name] + rescue + return "Unknown Item Group" + end + end + end +end \ No newline at end of file diff --git a/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/locations.rb b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/locations.rb new file mode 100644 index 0000000..185c384 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/locations.rb @@ -0,0 +1,78 @@ +module Archipelago + + class Client + + class Locations + + def initialize(client) + @client = client + @datapackages = {} + @checked_locations = [] + @missing_locations = [] + end + + def import_checked_locations(location_list) + @checked_locations = location_list + end + + def import_missing_locations(location_list) + @missing_locations = location_list + end + + def import_datapackages(datapackages) + @datapackages = datapackages if datapackages.is_a?(Hash) + end + + def check(*id_arguments) + if @client.client_connect_status == ConnectStatus::CONNECTED + id_arguments.each do |id| + @checked_locations << id if id.is_a?(Integer) + @checked_locations.concat(id) if id.is_a?(Array) + @checked_locations.concat(id.to_a) if id.is_a?(Range) + end + + check_packet = Packets::LocationChecks.new(@checked_locations) + @client.client_socket.send(check_packet.to_json) + else + puts "[LocationsManager check] You need to have an active Archipelago connection to use this!" + end + end + + def scout(hint_mode, *id_arguments) + if @client.client_connect_status == ConnectStatus::CONNECTED + scout_list = [] + id_arguments.each do |id| + scout_list << id if id.is_a?(Integer) + end + + scout_packet = Packets::LocationScouts.new(hint_mode, scout_list) + @client.client_socket.send(scout_packet.to_json) + else + puts "[LocationsManager scout] You need to have an active Archipelago connection to use this!" + end + end + + def name(game_name, id) + @datapackages[game_name]["location_name_to_id"].each do |location, value| + return location if value == id + end + return "Unknown Location" + end + + def group(game_name, group_name) + return @datapackages[game_name]["location_name_groups"][group_name] + rescue + return "Unknown Location Group" + end + + def auto_release + if @client.client_connect_status == ConnectStatus::CONNECTED + check_packet = Packets::LocationChecks.new(@missing_locations) + @client.client_socket.send(check_packet.to_json) + else + puts "[LocationsManager auto_release] You need to have an active Archipelago connection to use this!" + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/objects.rb b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/objects.rb new file mode 100644 index 0000000..5589e0f --- /dev/null +++ b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/objects.rb @@ -0,0 +1,205 @@ +module Archipelago + module Objects + + # ---------------------------------- + # MINOR OBJECTS + # These structures are referenced in other packets but are not packets themselves. + # ---------------------------------- + + # VERSION - This object defines an Archipelago version (i.e. 0.4.5) + class Version + attr_reader :major, :minor, :build, :class + + def initialize(major, minor, build) + @major = major + @minor = minor + @build = build + @class = "Version" + end + + def self.from_hash(data) + new(data['major'], data['minor'], data['build']) + end + + def to_hash + { + major: @major, + minor: @minor, + build: @build, + class: @class + } + end + end + + class NetworkPlayer + attr_reader :team, :slot, :alias, :name + + def initialize(team, slot, player_alias, player_name) + @team = team + @slot = slot + @alias = player_alias + @name = player_name + end + + def self.from_hash(data) + new(data['team'], data['slot'], data['alias'], data['name']) + end + + def to_hash + { + team: @team, + slot: @slot, + alias: @alias, + name: @name + } + end + end + + class NetworkItem + attr_reader :item, :location, :player, :flags + + def initialize(item, location, player, flags) + @item = item + @location = location + @player = player + @flags = flags + end + + def self.from_hash(data) + new(data['item'], data['location'], data['player'], data['flags']) + end + + def to_hash + { + item: @item, + location: @location, + player: @player, + flags: @flags + } + end + end + + class JSONMessagePart + #TODO: Add output function to console with color tags + attr_reader :type, :text, :color, :flags, :player + + def initialize(type:, text: nil, color: nil, flags: nil, player: nil) + @type = type + @text = text + @color = color + @flags = flags + @player = player + end + + def self.from_hash(data) + new( + type: data['type'], + text: data['text'], + color: data['color'], + flags: data['flags'], + player: data['player'] + ) + end + + def to_hash + { + type: @type, + text: @text, + color: @color, + flags: @flags, + player: @player + } + end + end + + class NetworkSlot + attr_reader :name, :game, :type, :group_members + + def initialize(name, game, type, group_members = []) + @name = name + @game = game + @type = type + @group_members = group_members + end + + def self.from_hash(data) + new( + data['name'], + data['game'], + data['type'], + data['group_members'] || [] # Populate group_members if available, otherwise use an empty array + ) + end + + def to_hash + { + name: @name, + game: @game, + type: @type, # Convert SlotType enum to string representation + group_members: @group_members + } + end + end + + class Hint + attr_reader :receiving_player, :finding_player, :location, :item, :found, :entrance, :item_flags + + def initialize(receiving_player, finding_player, location, item, found, entrance = "", item_flags = 0) + @receiving_player = receiving_player + @finding_player = finding_player + @location = location + @item = item + @found = found + @entrance = entrance + @item_flags = item_flags + end + + def self.from_hash(data) + new( + data['receiving_player'], + data['finding_player'], + data['location'], + data['item'], + data['found'], + data['entrance'] || "", + data['item_flags'] || 0 + ) + end + + def to_hash + { + receiving_player: @receiving_player, + finding_player: @finding_player, + location: @location, + item: @item, + found: @found, + entrance: @entrance, + item_flags: @item_flags + } + end + end + + class DataStorageOperation + attr_accessor :operation, :value + + def initialize(operation, value) + @operation = operation + @value = value + end + + def to_hash + { + operation: @operation, + value: @value + } + end + end + end +end + +def valid_json?(json_string) + JSON.parse(json_string, quirks_mode: true, valid: true) + true +rescue JSON::ParserError => e + false +end diff --git a/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/packets.rb b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/packets.rb new file mode 100644 index 0000000..891392e --- /dev/null +++ b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/packets.rb @@ -0,0 +1,421 @@ +module Archipelago + module Packets + # ---------------------------------- + # SERVER PACKETS + # These packets are only ever sent by the server. + # ---------------------------------- + + # ROOMINFO - This packet is part of the handshake process. Contains information about the multiworld. + class RoomInfo + attr_reader :cmd, :password, :games, :tags, :version, :generator_version, + :permissions, :hint_cost, :location_check_points, + :datapackage_versions, :datapackage_checksums, :seed_name, :time + + def initialize(data) + parse(data) + end + + def parse(data) + json_data = JSON.parse(data)[0] # Extract the hash from the array + @cmd = json_data['cmd'] + @password = json_data['password'] + @games = json_data['games'] + @tags = json_data['tags'] + @version = Objects::Version.from_hash(json_data['version']) + @generator_version = Objects::Version.from_hash(json_data['generator_version']) + @permissions = json_data['permissions'] + @hint_cost = json_data['hint_cost'] + @location_check_points = json_data['location_check_points'] + @datapackage_versions = json_data['datapackage_versions'] + @datapackage_checksums = json_data['datapackage_checksums'] + @seed_name = json_data['seed_name'] + @time = json_data['time'] + end + end + + class ConnectionRefused + attr_reader :cmd, :errors + + def initialize(data) + parse(data) + end + + def parse(data) + json_data = JSON.parse(data)[0] + @cmd = json_data['cmd'] + @errors = json_data['errors'] + end + end + + class Connected + attr_reader :cmd, :team, :slot, :players, :missing_locations, :checked_locations, + :slot_data, :slot_info, :hint_points + + def initialize(data) + parse(data) + end + + def parse(data) + json_data = JSON.parse(data)[0] + @cmd = json_data['cmd'] + @team = json_data['team'] + @slot = json_data['slot'] + @players = json_data['players'] # Should be NetworkPlayer object. + @missing_locations = json_data['missing_locations'] + @checked_locations = json_data['checked_locations'] + @slot_data = json_data['slot_data'] + @slot_info = json_data['slot_info'] # Should be NetworkSlot object. + @hint_points = json_data['hint_points'] + end + end + + class ReceivedItems + attr_reader :cmd, :index, :items + + def initialize(data) + parse(data) + end + + def parse(data) + json_data = JSON.parse(data)[0] + @cmd = json_data['cmd'] + @index = json_data['index'] + @items = json_data['items'] # Should be NetworkItem object. + end + end + + class LocationInfo + attr_reader :cmd, :locations + + def initialize(data) + parse(data) + end + + def parse(data) + json_data = JSON.parse(data)[0] + @cmd = json_data['cmd'] + @locations = json_data['locations'] # Should be NetworkItem object. + end + end + + class RoomUpdate + # NOTE: Class should never be initialized. Reserved for future use if need be. + # Call data.import_game_data(RoomUpdate) instead, with RoomUpdate being a hash. + end + + class PrintJSON + attr_reader :cmd, :data, :type, :receiving, :item, :found, :team, :slot, :message, :tags, :countdown + + def initialize(data) + parse(data) + end + + def parse(data) + json_data = JSON.parse(data)[0] + @cmd = json_data['cmd'] + @data = json_data['data'] + @type = json_data['type'] + @receiving = json_data['receiving'] + @item = json_data['item'] + @found = json_data['found'] + @team = json_data['team'] + @slot = json_data['slot'] + @message = json_data['message'] + @tags = json_data['tags'] + @countdown = json_data['countdown'] + end + + # TODO: Add string constructor method + end + + + class DataPackage + attr_reader :cmd, :data + + def initialize(data) + parse(data) + end + + def parse(data) + json_data = JSON.parse(data)[0] + @cmd = json_data['cmd'] + @data = json_data['data'] + end + end + + class Bounced + attr_reader :cmd, :games, :slots, :tags, :data + + def initialize(data) + parse(data) + end + + def parse(data) + json_data = JSON.parse(data)[0] + @cmd = json_data['cmd'] + @games = json_data['games'] + @slots = json_data['slots'] + @tags = json_data['tags'] + @data = json_data['data'] + end + end + + class InvalidPacket + attr_reader :cmd, :type, :original_cmd, :text + + def initialize(data) + parse(data) + end + + def parse(data) + json_data = JSON.parse(data)[0] + @cmd = json_data['cmd'] + @type = json_data['type'] + @original_cmd = json_data['original_cmd'] + @text = json_data['text'] + end + end + + class Retrieved + attr_reader :cmd, :keys + + def initialize(data) + parse(data) + end + + def parse(data) + json_data = JSON.parse(data)[0] + @cmd = json_data['cmd'] + @keys = json_data['keys'] + end + end + + class SetReply + attr_reader :cmd, :key, :value, :original_value + + def initialize(data) + parse(data) + end + + def parse(data) + json_data = JSON.parse(data)[0] + @cmd = json_data['cmd'] + @key = json_data['key'] + @value = json_data['value'] + @original_value = json_data['original_value'] + end + end + + # TODO: Make all the above packets have relevant methods + + # ---------------------------------- + # CLIENT PACKETS + # These packets are only ever sent by the client. + # ---------------------------------- + + # CONNECT - This packet is part of the handshake process. Contains information about the client. + class Connect + attr_accessor :password, :game, :name, :uuid, :version, :items_handling, :tags, :slot_data + + def initialize(password, game, name, uuid, version, items_handling, tags, slot_data) + @cmd = 'Connect' + @password = password + @game = game + @name = name + @uuid = uuid + @version = version.is_a?(Objects::Version) ? version.to_hash : version + @items_handling = items_handling + @tags = tags + @slot_data = slot_data + end + + def to_json(*args) + [{ + cmd: @cmd, + password: @password, + game: @game, + name: @name, + uuid: @uuid, + version: @version, + items_handling: @items_handling, + tags: @tags, + slot_data: @slot_data + }].to_json(*args) + end + + # TODO: Add ConnectUpdate method + end + + class Sync + + def initialize + @cmd = 'Sync' + end + + def to_json(*args) + [{ + cmd: @cmd + }].to_json(*args) + end + + end + + class LocationChecks + attr_accessor :locations + + def initialize(locations) + @cmd = 'LocationChecks' + @locations = locations # Should be list of ints + end + + def to_json(*args) + [{ + cmd: @cmd, + locations: @locations + }].to_json(*args) + end + end + + class LocationScouts + attr_accessor :locations, :create_as_hint + + def initialize(create_as_hint, locations) + @cmd = 'LocationScouts' + @locations = locations # Should be list of ints + @create_as_hint = create_as_hint + end + + def to_json(*args) + [{ + cmd: @cmd, + locations: @locations, + create_as_hint: @create_as_hint + }].to_json(*args) + end + end + + class StatusUpdate + attr_accessor :status + + def initialize(status) + @cmd = 'StatusUpdate' + @status = status + end + + def to_json(*args) + [{ + cmd: @cmd, + status: @status + }].to_json(*args) + end + end + + class Say + attr_accessor :text + + def initialize(text) + @cmd = 'Say' + @text = text + end + + def to_json(*args) + [{ + cmd: @cmd, + text: @text + }].to_json(*args) + end + end + + class GetDataPackage + attr_accessor :games + + def initialize(games) + @cmd = "GetDataPackage" + @games = games + end + + def to_json(*args) + [{ + cmd: @cmd, + games: @games + }].to_json(*args) + end + end + + class Bounce + attr_accessor :games, :slots, :tags, :data + + def initialize(games, slots, tags, data) + @cmd = "Bounce" + @games = games + @slots = slots + @tags = tags + @data = data + end + + def to_json(*args) + [{ + cmd: @cmd, + games: @games, + slots: @slots, + tags: @tags, + data: @data + }].to_json(*args) + end + end + + class Get + attr_accessor :keys + + def initialize(keys) + @cmd = "Get" + @keys = keys + end + + def to_json(*args) + [{ + cmd: @cmd, + keys: @keys + }].to_json(*args) + end + end + + class Set + attr_accessor :key, :default, :want_reply, :operations + + def initialize(key, default, want_reply, operations) + @cmd = "Set" + @key = key + @default = default + @want_reply = want_reply + @operations = operations + end + + def to_json(*args) + [{ + cmd: @cmd, + key: @key, + default: @default, + want_reply: @want_reply, + operations: @operations + }].to_json(*args) + end + end + + class SetNotify + attr_accessor :keys + + def initialize(keys) + @cmd = "SetNotify" + @keys = keys + end + + def to_json(*args) + [{ + cmd: @cmd, + keys: @keys + }].to_json(*args) + end + end + end +end \ No newline at end of file diff --git a/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/players.rb b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/players.rb new file mode 100644 index 0000000..7b9aa9e --- /dev/null +++ b/games/FNaFB2/Ruby/gems/archipelago_rb/archipelago_rb/players.rb @@ -0,0 +1,40 @@ +module Archipelago + + class Client + + class Players + + def initialize(client) + @client = client + end + + def get(player_id) + if @client.client_connect_status == ConnectStatus::CONNECTED + @client.data.players.each do |player| + return player if player["slot"] == player_id + end + else + puts "[PlayersManager get] You need an active Archipelago connection to use this!" + end + end + + def all + return @client.data.players + end + + def method_missing(method_name, *args) + if @client.client_connect_status == ConnectStatus::CONNECTED + if args.length > 1 + puts "[PlayersManager #{method_name.to_s}] Too many arguments!" + else + @client.data.players.each do |player| + return player[method_name.to_s] if player["slot"] == args[0] + end + end + else + puts "[PlayersManager #{method_name.to_s}] You need an active Archipelago connection to use this!" + end + end + end + end +end \ No newline at end of file diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/.gitignore b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/.gitignore new file mode 100644 index 0000000..43bbef6 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/.gitignore @@ -0,0 +1,24 @@ +.DS_Store +*.tmp +*~ +*#* +vendor +.sass-cache +.bundle +config.yml +*.gem +*.rbc +.config +.yardoc +InstalledFiles +_yardoc +coverage +doc/ +lib/bundler/man +pkg +rdoc +spec/reports +test/tmp +test/version_tmp +tmp +.ruby-version \ No newline at end of file diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/.travis.yml b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/.travis.yml new file mode 100644 index 0000000..9bb57b8 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/.travis.yml @@ -0,0 +1,7 @@ +language: ruby +rvm: + - 2.1.0 + - 2.2.7 + - 2.3.4 + - 2.4.1 + diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/Gemfile b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/Gemfile new file mode 100644 index 0000000..c0c4bae --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +# Specify your gem's dependencies in event_emitter.gemspec +gemspec diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/History.txt b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/History.txt new file mode 100644 index 0000000..d570448 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/History.txt @@ -0,0 +1,63 @@ +=== 0.2.6 2013-07-25 + +* Update Travis ruby versions (#16) +* Fix Fixnum warning on Ruby 2.4+ (#15) + +=== 0.2.5 2013-03-31 + +* add benchmark + +=== 0.2.4 2013-03-21 + +* bugfix multiple once error + +=== 0.2.3 2013-03-05 + +* catch all events with "EventEmitter#on :*" + +=== 0.2.2 2013-01-04 + +* bugfix + +=== 0.2.1 2013-01-04 + +* use bundler gem template + +=== 0.2.0 2012-12-16 + +* remove_listener +* fix method-name duplication + +=== 0.1.0 2012-11-15 + +* support on/emit multiple arguments + +=== 0.0.7 2012-11-09 + +* on/emit without any args +* add tests + +=== 0.0.6 2012-11-09 + +* add sample + +=== 0.0.5 2012-11-08 + +* add github page link + +=== 0.0.4 2012-11-08 + +* instance-specific method with EventEmitter.apply(instance) + +=== 0.0.3 2012-11-08 + +* call listener with Object#instance_exec + +=== 0.0.2 2012-11-07 + +* EventEmitter#once : call listener only first time +* EventEmitter#add_listener, remove_listener + +=== 0.0.1 2012-11-07 + +* implement "on" and "emit" diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/LICENSE.txt b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/LICENSE.txt new file mode 100644 index 0000000..9752632 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2012 Sho Hashimoto + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/README.md b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/README.md new file mode 100644 index 0000000..a06b209 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/README.md @@ -0,0 +1,119 @@ +event_emitter +============= + +* Ruby port of EventEmitter from Node.js +* http://shokai.github.com/event_emitter + +[![Build Status](https://travis-ci.org/shokai/event_emitter.svg)](https://travis-ci.org/shokai/event_emitter) + + +Install +------- + + % gem install event_emitter + + +Requirements +------------ + +testing on + +* Ruby 1.8.7 +* Ruby 1.9.2 +* Ruby 2.0.0 +* Ruby 2.1.0 +* JRuby + + +Synopsys +-------- + +load rubygem +```ruby +require "rubygems" +require "event_emitter" +``` + +include +```ruby +class User + include EventEmitter + attr_accessor :name +end +``` + +regist event listener +```ruby +user = User.new +user.name = "shokai" +user.on :go do |data| + puts "#{name} go to #{data[:place]}" +end +``` + +call event +```ruby +user.emit :go, {:place => "mountain"} +# => "shokai go to mountain" +``` + +regist event using "once" +```ruby +user.once :eat do |what, where| + puts "#{name} -> eat #{what} at #{where}" +end +``` + +call +```ruby +user.emit :eat, "BEEF", "zanmai" # => "shokai -> eat BEEF at zanmai" +user.emit :eat, "Ramen", "marutomo" # => do not call. call only first time. +``` + +apply as instance-specific method +```ruby +class Foo +end + +foo = Foo.new +EventEmitter.apply foo +``` + +remove event listener +```ruby +user.remove_listener :go +user.remove_listener event_id +``` + +catch all events +```ruby +user.on :* do |event_name, args| + puts event_name + " called" + p args +end +``` + +see samples https://github.com/shokai/event_emitter/tree/master/samples + + +Test +---- + + % gem install bundler + % bundle install + % rake test + + +Benchmark +--------- + + % rake benchmark + + +Contributing +------------ +1. Fork it +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Add some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create new Pull Request \ No newline at end of file diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/Rakefile b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/Rakefile new file mode 100644 index 0000000..30846eb --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/Rakefile @@ -0,0 +1,14 @@ +require "bundler/gem_tasks" +require "rake/testtask" + +Rake::TestTask.new do |t| + t.pattern = "test/test_*.rb" +end + +task :default => :test + +desc "run eventemitter benchmark" +task :benchmark do + require File.expand_path 'benchmark/benchmark', File.dirname(__FILE__) + Bench.run +end diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/benchmark/benchmark.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/benchmark/benchmark.rb new file mode 100644 index 0000000..c5304a2 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/benchmark/benchmark.rb @@ -0,0 +1,57 @@ +#!/usr/bin/env ruby +require File.expand_path 'benchmark_helper', File.dirname(__FILE__) + +class Bench + + class Foo + include EventEmitter + end + + def bench_1on_100Kemit + foo = Foo.new + count = 0 + foo.on :bar do |num| + count += num + end + 100000.times do + foo.emit :bar, 1 + end + raise Error, "test code error" unless count == 100000 + end + + def bench_1Kon_1Kemit + foo = Foo.new + count = 0 + (1000-1).times do + foo.on :bar do + end + end + foo.on :bar do |num| + count += num + end + 1000.times do + foo.emit :bar, 1 + end + raise Error, "test code error" unless count == 1000 + end + + def bench_100Kon_1emit + foo = Foo.new + count = 0 + 1.upto(100000-1).each do |i| + foo.on "bar_#{i}" do + end + end + foo.on :bar do |num| + count += num + end + foo.emit :bar, 1 + raise Error, "test code error" unless count == 1 + end + +end + + +if __FILE__ == $0 + Bench.run +end diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/benchmark/benchmark_helper.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/benchmark/benchmark_helper.rb new file mode 100644 index 0000000..16e6cef --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/benchmark/benchmark_helper.rb @@ -0,0 +1,22 @@ +$:.unshift File.expand_path '../lib', File.dirname(__FILE__) +require 'event_emitter' +require 'benchmark' + +class Bench + + class Error < StandardError + end + + def self.run + puts "ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]" + bench = self.new + Benchmark.bm do |x| + bench.methods.select{|i| i.to_s =~ /^bench_(.+)$/}.sort.each do |m| + x.report m.to_s.scan(/^bench_(.+)$/)[0][0] do + bench.__send__ m + end + end + end + end + +end diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/event_emitter.gemspec b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/event_emitter.gemspec new file mode 100644 index 0000000..afed763 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/event_emitter.gemspec @@ -0,0 +1,22 @@ +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'event_emitter/version' + +Gem::Specification.new do |gem| + gem.name = "event_emitter" + gem.version = EventEmitter::VERSION + gem.authors = ["Sho Hashimoto"] + gem.email = ["hashimoto@shokai.org"] + gem.description = %q{Ruby port of EventEmitter from Node.js} + gem.summary = gem.description + gem.homepage = "http://shokai.github.com/event_emitter" + + gem.files = `git ls-files`.split($/).reject{|i| i=="Gemfile.lock" } + gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } + gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) + gem.require_paths = ["lib"] + + gem.add_development_dependency "minitest" + gem.add_development_dependency "rake" + gem.add_development_dependency "bundler", "~> 1.15" +end diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/lib/event_emitter.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/lib/event_emitter.rb new file mode 100644 index 0000000..8c62ca1 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/lib/event_emitter.rb @@ -0,0 +1,5 @@ +$:.unshift(File.dirname(__FILE__)) unless + $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) + +require 'event_emitter/emitter' +require 'event_emitter/version' diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/lib/event_emitter/emitter.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/lib/event_emitter/emitter.rb new file mode 100644 index 0000000..444c13c --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/lib/event_emitter/emitter.rb @@ -0,0 +1,71 @@ + +module EventEmitter + def self.included(klass) + # klass.extend ClassMethods + klass.__send__ :include, InstanceMethods + end + + def self.apply(object) + object.extend InstanceMethods + end + + module ClassMethods + end + + module InstanceMethods + def __events + @__events ||= [] + end + + def add_listener(type, params={}, &block) + raise ArgumentError, 'listener block not given' unless block_given? + id = __events.empty? ? 0 : __events.last[:id]+1 + __events << { + :type => type.to_sym, + :listener => block, + :params => params, + :id => id + } + id + end + + alias :on :add_listener + + def remove_listener(id_or_type) + if id_or_type.is_a? Integer + __events.delete_if do |e| + e[:id] == id_or_type + end + elsif [String, Symbol].include? id_or_type.class + __events.delete_if do |e| + e[:type] == id_or_type.to_sym + end + end + end + + def emit(type, *data) + type = type.to_sym + __events.each do |e| + case e[:type] + when type + listener = e[:listener] + e[:type] = nil if e[:params][:once] + instance_exec(*data, &listener) + when :* + listener = e[:listener] + e[:type] = nil if e[:params][:once] + instance_exec(type, *data, &listener) + end + end + __events.each do |e| + remove_listener e[:id] unless e[:type] + end + end + + def once(type, &block) + add_listener type, {:once => true}, &block + end + + end + +end diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/lib/event_emitter/version.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/lib/event_emitter/version.rb new file mode 100644 index 0000000..b00ee42 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/lib/event_emitter/version.rb @@ -0,0 +1,3 @@ +module EventEmitter + VERSION = '0.2.6' +end diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/samples/class-method.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/samples/class-method.rb new file mode 100644 index 0000000..431eabe --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/samples/class-method.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +$:.unshift File.expand_path '../lib', File.dirname(__FILE__) +require 'event_emitter' + +class DB + def self.connect + self.emit :connect, :connected + end +end + +EventEmitter.apply DB + +DB.on :connect do |status| + puts status +end + +DB.connect diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/samples/instance-specific-method.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/samples/instance-specific-method.rb new file mode 100644 index 0000000..b883cfd --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/samples/instance-specific-method.rb @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +$:.unshift File.expand_path '../lib', File.dirname(__FILE__) +require 'event_emitter' + +class User + attr_accessor :name + def initialize(name) + @name = name + end +end + +shokai = User.new "shokai" +ymrl = User.new "ymrl" +EventEmitter.apply shokai ## set instance-specific method + +shokai.on :go do |data| + puts "#{name} go to #{data[:place]}" +end + +shokai.emit :go, :place => "chiba city" + +## raise undefined-method error +begin + ymrl.on :go do |data| + puts "#{name} go to #{data[:place]}" + end +rescue => e + STDERR.puts e +end diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/samples/sample.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/samples/sample.rb new file mode 100644 index 0000000..bc2a4e7 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/samples/sample.rb @@ -0,0 +1,33 @@ +#!/usr/bin/env ruby +$:.unshift File.expand_path '../lib', File.dirname(__FILE__) +require 'event_emitter' + +class User + include EventEmitter + attr_accessor :name + + def initialize(name) + @name = name + end +end + +shokai = User.new 'shokai' +ymrl = User.new 'ymrl' + +shokai.on :go do |data| + puts "#{name} go to #{data[:place]}" +end +ymrl.on :go do |data| + puts "#{name} go to #{data[:place]}" +end + +shokai.emit :go, {:place => 'mountain'} +ymrl.emit :go, :place => 'cyberspace' + + +shokai.once :eat do |what, where| + puts "#{name} -> #{what} at #{where}" +end + +shokai.emit :eat, 'BEEF', 'zanmai' +shokai.emit :eat, 'Ramen', 'marutomo' # do not call. call only first time if regist with "once" diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/samples/timer.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/samples/timer.rb new file mode 100644 index 0000000..e0548d0 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/samples/timer.rb @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby +$:.unshift File.expand_path '../lib', File.dirname(__FILE__) +require 'event_emitter' + +class Timer + include EventEmitter + + def start(sec, count) + count.times do + sleep sec + emit :tick + end + emit :end + end +end + +timer = Timer.new + +timer.on :tick do + puts Time.now +end + +timer.once :tick do + puts "timer start" +end + +timer.on :end do + puts "timer end" +end + +timer.start 1, 5 diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_catch_all_events.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_catch_all_events.rb new file mode 100644 index 0000000..c764f41 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_catch_all_events.rb @@ -0,0 +1,61 @@ +require File.expand_path 'test_helper', File.dirname(__FILE__) + +class TestCatchAllEvents < MiniTest::Test + + class Foo + include EventEmitter + attr_accessor :created_at + end + + def setup + @foo = Foo.new + @foo.created_at = @now = Time.now + end + + def test_catch_all_emits + created_at = nil + created_at_ = nil + called_event = nil + @foo.on :* do |event| + called_event = event + created_at = self.created_at + end + @foo.on :bar do + created_at_ = self.created_at + end + @foo.emit :bar + + assert created_at == @now + assert called_event == :bar + assert created_at_ == @now + end + + def test_catch_all_emits_with_args + arg1_ = nil + arg2_ = nil + called_event = nil + @foo.on :* do |event, arg1, arg2| + called_event = event + arg1_ = arg1 + arg2_ = arg2 + end + @foo.emit :bar, 'kazusuke', 'zanmai' + + assert called_event == :bar + assert arg1_ == 'kazusuke' + assert arg2_ == 'zanmai' + end + + def test_once + total = 0 + @foo.once :* do |event, data| + total += data[:num] if event == :add + end + + @foo.emit :add, :num => 10 + assert total == 10, 'first call' + @foo.emit :add, :num => 5 + assert total == 10, 'call listener only first time' + end + +end diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_class_method.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_class_method.rb new file mode 100644 index 0000000..3c2055c --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_class_method.rb @@ -0,0 +1,113 @@ +require File.expand_path 'test_helper', File.dirname(__FILE__) + +class TestClassMethod < MiniTest::Test + + class Foo + def self.created_at + @@created_at + end + def self.created_at=(time) + @@created_at = time + end + end + + def setup + Foo.created_at = @now = Time.now + EventEmitter.apply Foo + end + + def test_simple + created_at = nil + Foo.on :bar do + created_at = self.created_at + end + Foo.emit :bar + + assert created_at == @now + end + + def test_on_emit + result = nil + created_at = nil + Foo.on :chat do |data| + result = data + created_at = self.created_at + end + + Foo.emit :chat, :user => 'shokai', :message => 'hello world' + + assert result[:user] == 'shokai' + assert result[:message] == 'hello world' + assert created_at == @now, 'instance method' + end + + def test_on_emit_multiargs + _user = nil + _message = nil + _session = nil + created_at = nil + Foo.on :chat2 do |user, message, session| + _user = user + _message = message + _session = session + created_at = self.created_at + end + + sid = Time.now.to_i + Foo.emit :chat2, 'shokai', 'hello world', sid + + assert _user == 'shokai' + assert _message == 'hello world' + assert _session == sid + assert created_at == @now, 'instance method' + end + + def test_add_listener + result = nil + created_at = nil + Foo.add_listener :chat do |data| + result = data + created_at = self.created_at + end + + Foo.emit :chat, :user => 'shokai', :message => 'hello world' + + assert result[:user] == 'shokai' + assert result[:message] == 'hello world' + assert created_at == @now, 'instance method' + end + + def test_remove_listener + size = Foo.__events.size + + Foo.on :foo do |data| + puts "bar #{data}" + end + Foo.on :foo do |data| + puts "barbar: #{data}" + end + + id = Foo.on :baz do |data| + p data + end + + assert Foo.__events.size == size+3, 'check registerd listener count' + Foo.remove_listener id + assert Foo.__events.size == size+2, 'remove listener by id' + + Foo.remove_listener :foo + assert Foo.__events.size == size, 'remove all "foo" listener' + end + + def test_once + total = 0 + Foo.once :add do |data| + total += data + end + + Foo.emit :add, 1 + assert total == 1, 'first call' + Foo.emit :add, 1 + assert total == 1, 'call listener only first time' + end +end diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_event_emitter.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_event_emitter.rb new file mode 100644 index 0000000..b1b7376 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_event_emitter.rb @@ -0,0 +1,143 @@ +require File.expand_path 'test_helper', File.dirname(__FILE__) + +class TestEventEmitter < MiniTest::Test + + class Foo + include EventEmitter + attr_accessor :created_at + end + + def setup + @foo = Foo.new + @foo.created_at = @now = Time.now + end + + def test_simple + created_at = nil + @foo.on :bar do + created_at = self.created_at + end + @foo.emit :bar + + assert created_at == @now + end + + def test_string_event_name + created_at = nil + @foo.on "bar" do + created_at = self.created_at + end + @foo.emit :bar + end + + def test_on_emit + result = nil + created_at = nil + @foo.on :chat do |data| + result = data + created_at = self.created_at + end + + @foo.emit :chat, :user => 'shokai', :message => 'hello world' + + assert result[:user] == 'shokai' + assert result[:message] == 'hello world' + assert created_at == @now, 'instance method' + end + + def test_on_emit_multiargs + _user = nil + _message = nil + _session = nil + created_at = nil + @foo.on :chat do |user, message, session| + _user = user + _message = message + _session = session + created_at = self.created_at + end + + sid = Time.now.to_i + @foo.emit :chat, 'shokai', 'hello world', sid + + assert _user == 'shokai' + assert _message == 'hello world' + assert _session == sid + assert created_at == @now, 'instance method' + end + + def test_add_listener + result = nil + created_at = nil + @foo.add_listener :chat do |data| + result = data + created_at = self.created_at + end + + @foo.emit :chat, :user => 'shokai', :message => 'hello world' + + assert result[:user] == 'shokai' + assert result[:message] == 'hello world' + assert created_at == @now, 'instance method' + end + + def test_remove_listener + @foo.on :bar do |data| + puts "bar #{data}" + end + @foo.on :bar do |data| + puts "barbar: #{data}" + end + + id = @foo.on :baz do |data| + p data + end + + assert @foo.__events.size == 3, 'check registerd listener count' + @foo.remove_listener id + assert @foo.__events.size == 2, 'remove listener by id' + + @foo.remove_listener :bar + assert @foo.__events.size == 0, 'remove all "bar" listener' + end + + def test_once + total = 0 + @foo.once :add do |num| + total += num + end + + @foo.emit :add, 1 + assert total == 1, 'first call' + @foo.emit :add, 1 + assert total == 1, 'call listener only first time' + end + + def test_multiple_once + total = 0 + @foo.on :add do |num| + total += num + end + + @foo.once :add do |num| + total += num + end + + @foo.once :add do |num| + total += num + end + + @foo.once :add do |num| + total += num + end + + @foo.once :add do |num| + total += num + end + + @foo.emit :add, 1 + assert total == 5, 'first call' + @foo.emit :add, 1 + assert total == 6, 'call' + end +end diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_helper.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_helper.rb new file mode 100644 index 0000000..2f4ed46 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_helper.rb @@ -0,0 +1,6 @@ +require 'rubygems' +require 'bundler/setup' +require 'minitest/autorun' + +$:.unshift File.expand_path '../lib', File.dirname(__FILE__) +require 'event_emitter' diff --git a/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_singular_method.rb b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_singular_method.rb new file mode 100644 index 0000000..0add7f8 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/event_emitter-0.2.6/test/test_singular_method.rb @@ -0,0 +1,107 @@ +require File.expand_path 'test_helper', File.dirname(__FILE__) + +class TestSingularMethod < MiniTest::Test + + class Foo + attr_accessor :created_at + end + + def setup + @foo = Foo.new + @foo.created_at = @now = Time.now + EventEmitter.apply @foo + end + + def test_simple + created_at = nil + @foo.on :bar do + created_at = self.created_at + end + @foo.emit :bar + + assert created_at == @now + end + + def test_on_emit + result = nil + created_at = nil + @foo.on :chat do |data| + result = data + created_at = self.created_at + end + + @foo.emit :chat, :user => 'shokai', :message => 'hello world' + + assert result[:user] == 'shokai' + assert result[:message] == 'hello world' + assert created_at == @now, 'instance method' + end + + def test_on_emit_multiargs + _user = nil + _message = nil + _session = nil + created_at = nil + @foo.on :chat do |user, message, session| + _user = user + _message = message + _session = session + created_at = self.created_at + end + + sid = Time.now.to_i + @foo.emit :chat, 'shokai', 'hello world', sid + + assert _user == 'shokai' + assert _message == 'hello world' + assert _session == sid + assert created_at == @now, 'instance method' + end + + def test_add_listener + result = nil + created_at = nil + @foo.add_listener :chat do |data| + result = data + created_at = self.created_at + end + + @foo.emit :chat, :user => 'shokai', :message => 'hello world' + + assert result[:user] == 'shokai' + assert result[:message] == 'hello world' + assert created_at == @now, 'instance method' + end + + def test_remove_listener + @foo.on :bar do |data| + puts "bar #{data}" + end + @foo.on :bar do |data| + puts "barbar: #{data}" + end + + id = @foo.on :baz do |data| + p data + end + + assert @foo.__events.size == 3, 'check registerd listener count' + @foo.remove_listener id + assert @foo.__events.size == 2, 'remove listener by id' + + @foo.remove_listener :bar + assert @foo.__events.size == 0, 'remove all "bar" listener' + end + + def test_once + total = 0 + @foo.once :add do |data| + total += data + end + + @foo.emit :add, 1 + assert total == 1, 'first call' + @foo.emit :add, 1 + assert total == 1, 'call listener only first time' + end +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/bigdecimal.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/bigdecimal.rb new file mode 100644 index 0000000..b1d0cfa --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/bigdecimal.rb @@ -0,0 +1,58 @@ +#frozen_string_literal: false +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +begin + require 'bigdecimal' +rescue LoadError +end + +class BigDecimal + + # See #as_json. + def self.json_create(object) + BigDecimal._load object['b'] + end + + # Methods BigDecimal#as_json and +BigDecimal.json_create+ may be used + # to serialize and deserialize a \BigDecimal object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method BigDecimal#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/bigdecimal' + # x = BigDecimal(2).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"} + # y = BigDecimal(2.0, 4).as_json # => {"json_class"=>"BigDecimal", "b"=>"36:0.2e1"} + # z = BigDecimal(Complex(2, 0)).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"} + # + # \Method +JSON.create+ deserializes such a hash, returning a \BigDecimal object: + # + # BigDecimal.json_create(x) # => 0.2e1 + # BigDecimal.json_create(y) # => 0.2e1 + # BigDecimal.json_create(z) # => 0.2e1 + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'b' => _dump, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/bigdecimal' + # puts BigDecimal(2).to_json + # puts BigDecimal(2.0, 4).to_json + # puts BigDecimal(Complex(2, 0)).to_json + # + # Output: + # + # {"json_class":"BigDecimal","b":"27:0.2e1"} + # {"json_class":"BigDecimal","b":"36:0.2e1"} + # {"json_class":"BigDecimal","b":"27:0.2e1"} + # + def to_json(*args) + as_json.to_json(*args) + end +end if defined?(::BigDecimal) diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/complex.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/complex.rb new file mode 100644 index 0000000..ef48c55 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/complex.rb @@ -0,0 +1,51 @@ +#frozen_string_literal: false +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Complex + + # See #as_json. + def self.json_create(object) + Complex(object['r'], object['i']) + end + + # Methods Complex#as_json and +Complex.json_create+ may be used + # to serialize and deserialize a \Complex object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method Complex#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/complex' + # x = Complex(2).as_json # => {"json_class"=>"Complex", "r"=>2, "i"=>0} + # y = Complex(2.0, 4).as_json # => {"json_class"=>"Complex", "r"=>2.0, "i"=>4} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Complex object: + # + # Complex.json_create(x) # => (2+0i) + # Complex.json_create(y) # => (2.0+4i) + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'r' => real, + 'i' => imag, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/complex' + # puts Complex(2).to_json + # puts Complex(2.0, 4).to_json + # + # Output: + # + # {"json_class":"Complex","r":2,"i":0} + # {"json_class":"Complex","r":2.0,"i":4} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/core.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/core.rb new file mode 100644 index 0000000..bfb017c --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/core.rb @@ -0,0 +1,12 @@ +#frozen_string_literal: false +# This file requires the implementations of ruby core's custom objects for +# serialisation/deserialisation. + +require 'json/add/date' +require 'json/add/date_time' +require 'json/add/exception' +require 'json/add/range' +require 'json/add/regexp' +require 'json/add/struct' +require 'json/add/symbol' +require 'json/add/time' diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/date.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/date.rb new file mode 100644 index 0000000..19688f7 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/date.rb @@ -0,0 +1,54 @@ +#frozen_string_literal: false +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +require 'date' + +class Date + + # See #as_json. + def self.json_create(object) + civil(*object.values_at('y', 'm', 'd', 'sg')) + end + + alias start sg unless method_defined?(:start) + + # Methods Date#as_json and +Date.json_create+ may be used + # to serialize and deserialize a \Date object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method Date#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/date' + # x = Date.today.as_json + # # => {"json_class"=>"Date", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Date object: + # + # Date.json_create(x) + # # => # + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'y' => year, + 'm' => month, + 'd' => day, + 'sg' => start, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/date' + # puts Date.today.to_json + # + # Output: + # + # {"json_class":"Date","y":2023,"m":11,"d":21,"sg":2299161.0} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/date_time.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/date_time.rb new file mode 100644 index 0000000..d7d4259 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/date_time.rb @@ -0,0 +1,67 @@ +#frozen_string_literal: false +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +require 'date' + +class DateTime + + # See #as_json. + def self.json_create(object) + args = object.values_at('y', 'm', 'd', 'H', 'M', 'S') + of_a, of_b = object['of'].split('/') + if of_b and of_b != '0' + args << Rational(of_a.to_i, of_b.to_i) + else + args << of_a + end + args << object['sg'] + civil(*args) + end + + alias start sg unless method_defined?(:start) + + # Methods DateTime#as_json and +DateTime.json_create+ may be used + # to serialize and deserialize a \DateTime object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method DateTime#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/datetime' + # x = DateTime.now.as_json + # # => {"json_class"=>"DateTime", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0} + # + # \Method +JSON.create+ deserializes such a hash, returning a \DateTime object: + # + # DateTime.json_create(x) # BUG? Raises Date::Error "invalid date" + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'y' => year, + 'm' => month, + 'd' => day, + 'H' => hour, + 'M' => min, + 'S' => sec, + 'of' => offset.to_s, + 'sg' => start, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/datetime' + # puts DateTime.now.to_json + # + # Output: + # + # {"json_class":"DateTime","y":2023,"m":11,"d":21,"sg":2299161.0} + # + def to_json(*args) + as_json.to_json(*args) + end +end + + diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/exception.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/exception.rb new file mode 100644 index 0000000..71d8deb --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/exception.rb @@ -0,0 +1,49 @@ +#frozen_string_literal: false +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Exception + + # See #as_json. + def self.json_create(object) + result = new(object['m']) + result.set_backtrace object['b'] + result + end + + # Methods Exception#as_json and +Exception.json_create+ may be used + # to serialize and deserialize a \Exception object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method Exception#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/exception' + # x = Exception.new('Foo').as_json # => {"json_class"=>"Exception", "m"=>"Foo", "b"=>nil} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Exception object: + # + # Exception.json_create(x) # => # + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'm' => message, + 'b' => backtrace, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/exception' + # puts Exception.new('Foo').to_json + # + # Output: + # + # {"json_class":"Exception","m":"Foo","b":null} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/ostruct.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/ostruct.rb new file mode 100644 index 0000000..498de17 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/ostruct.rb @@ -0,0 +1,51 @@ +#frozen_string_literal: false +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +require 'ostruct' + +class OpenStruct + + # See #as_json. + def self.json_create(object) + new(object['t'] || object[:t]) + end + + # Methods OpenStruct#as_json and +OpenStruct.json_create+ may be used + # to serialize and deserialize a \OpenStruct object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method OpenStruct#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/ostruct' + # x = OpenStruct.new('name' => 'Rowdy', :age => nil).as_json + # # => {"json_class"=>"OpenStruct", "t"=>{:name=>'Rowdy', :age=>nil}} + # + # \Method +JSON.create+ deserializes such a hash, returning a \OpenStruct object: + # + # OpenStruct.json_create(x) + # # => # + # + def as_json(*) + klass = self.class.name + klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" + { + JSON.create_id => klass, + 't' => table, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/ostruct' + # puts OpenStruct.new('name' => 'Rowdy', :age => nil).to_json + # + # Output: + # + # {"json_class":"OpenStruct","t":{'name':'Rowdy',"age":null}} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/range.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/range.rb new file mode 100644 index 0000000..53f54ac --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/range.rb @@ -0,0 +1,54 @@ +#frozen_string_literal: false +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Range + + # See #as_json. + def self.json_create(object) + new(*object['a']) + end + + # Methods Range#as_json and +Range.json_create+ may be used + # to serialize and deserialize a \Range object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method Range#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/range' + # x = (1..4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, false]} + # y = (1...4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, true]} + # z = ('a'..'d').as_json # => {"json_class"=>"Range", "a"=>["a", "d", false]} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Range object: + # + # Range.json_create(x) # => 1..4 + # Range.json_create(y) # => 1...4 + # Range.json_create(z) # => "a".."d" + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'a' => [ first, last, exclude_end? ] + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/range' + # puts (1..4).to_json + # puts (1...4).to_json + # puts ('a'..'d').to_json + # + # Output: + # + # {"json_class":"Range","a":[1,4,false]} + # {"json_class":"Range","a":[1,4,true]} + # {"json_class":"Range","a":["a","d",false]} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/rational.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/rational.rb new file mode 100644 index 0000000..8c39a7d --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/rational.rb @@ -0,0 +1,49 @@ +#frozen_string_literal: false +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Rational + + # See #as_json. + def self.json_create(object) + Rational(object['n'], object['d']) + end + + # Methods Rational#as_json and +Rational.json_create+ may be used + # to serialize and deserialize a \Rational object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method Rational#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/rational' + # x = Rational(2, 3).as_json + # # => {"json_class"=>"Rational", "n"=>2, "d"=>3} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Rational object: + # + # Rational.json_create(x) + # # => (2/3) + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'n' => numerator, + 'd' => denominator, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/rational' + # puts Rational(2, 3).to_json + # + # Output: + # + # {"json_class":"Rational","n":2,"d":3} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/regexp.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/regexp.rb new file mode 100644 index 0000000..b63f496 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/regexp.rb @@ -0,0 +1,48 @@ +#frozen_string_literal: false +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Regexp + + # See #as_json. + def self.json_create(object) + new(object['s'], object['o']) + end + + # Methods Regexp#as_json and +Regexp.json_create+ may be used + # to serialize and deserialize a \Regexp object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method Regexp#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/regexp' + # x = /foo/.as_json + # # => {"json_class"=>"Regexp", "o"=>0, "s"=>"foo"} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Regexp object: + # + # Regexp.json_create(x) # => /foo/ + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'o' => options, + 's' => source, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/regexp' + # puts /foo/.to_json + # + # Output: + # + # {"json_class":"Regexp","o":0,"s":"foo"} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/set.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/set.rb new file mode 100644 index 0000000..1918353 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/set.rb @@ -0,0 +1,48 @@ +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +defined?(::Set) or require 'set' + +class Set + + # See #as_json. + def self.json_create(object) + new object['a'] + end + + # Methods Set#as_json and +Set.json_create+ may be used + # to serialize and deserialize a \Set object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method Set#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/set' + # x = Set.new(%w/foo bar baz/).as_json + # # => {"json_class"=>"Set", "a"=>["foo", "bar", "baz"]} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Set object: + # + # Set.json_create(x) # => # + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'a' => to_a, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/set' + # puts Set.new(%w/foo bar baz/).to_json + # + # Output: + # + # {"json_class":"Set","a":["foo","bar","baz"]} + # + def to_json(*args) + as_json.to_json(*args) + end +end + diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/struct.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/struct.rb new file mode 100644 index 0000000..8684776 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/struct.rb @@ -0,0 +1,52 @@ +#frozen_string_literal: false +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Struct + + # See #as_json. + def self.json_create(object) + new(*object['v']) + end + + # Methods Struct#as_json and +Struct.json_create+ may be used + # to serialize and deserialize a \Struct object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method Struct#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/struct' + # Customer = Struct.new('Customer', :name, :address, :zip) + # x = Struct::Customer.new.as_json + # # => {"json_class"=>"Struct::Customer", "v"=>[nil, nil, nil]} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Struct object: + # + # Struct::Customer.json_create(x) + # # => # + # + def as_json(*) + klass = self.class.name + klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" + { + JSON.create_id => klass, + 'v' => values, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/struct' + # Customer = Struct.new('Customer', :name, :address, :zip) + # puts Struct::Customer.new.to_json + # + # Output: + # + # {"json_class":"Struct","t":{'name':'Rowdy',"age":null}} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/symbol.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/symbol.rb new file mode 100644 index 0000000..b5f3623 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/symbol.rb @@ -0,0 +1,48 @@ + +#frozen_string_literal: false +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Symbol + + # Methods Symbol#as_json and +Symbol.json_create+ may be used + # to serialize and deserialize a \Symbol object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method Symbol#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/symbol' + # x = :foo.as_json + # # => {"json_class"=>"Symbol", "s"=>"foo"} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Symbol object: + # + # Symbol.json_create(x) # => :foo + # + def as_json(*) + { + JSON.create_id => self.class.name, + 's' => to_s, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/symbol' + # puts :foo.to_json + # + # Output: + # + # # {"json_class":"Symbol","s":"foo"} + # + def to_json(*a) + as_json.to_json(*a) + end + + # See #as_json. + def self.json_create(o) + o['s'].to_sym + end +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/add/time.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/add/time.rb new file mode 100644 index 0000000..599ed9e --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/add/time.rb @@ -0,0 +1,59 @@ +#frozen_string_literal: false +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Time + + # See #as_json. + def self.json_create(object) + if usec = object.delete('u') # used to be tv_usec -> tv_nsec + object['n'] = usec * 1000 + end + if method_defined?(:tv_nsec) + at(object['s'], Rational(object['n'], 1000)) + else + at(object['s'], object['n'] / 1000) + end + end + + # Methods Time#as_json and +Time.json_create+ may be used + # to serialize and deserialize a \Time object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method Time#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/time' + # x = Time.now.as_json + # # => {"json_class"=>"Time", "s"=>1700931656, "n"=>472846644} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Time object: + # + # Time.json_create(x) + # # => 2023-11-25 11:00:56.472846644 -0600 + # + def as_json(*) + nanoseconds = [ tv_usec * 1000 ] + respond_to?(:tv_nsec) and nanoseconds << tv_nsec + nanoseconds = nanoseconds.max + { + JSON.create_id => self.class.name, + 's' => tv_sec, + 'n' => nanoseconds, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/time' + # puts Time.now.to_json + # + # Output: + # + # {"json_class":"Time","s":1700931678,"n":980650786} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/common.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/common.rb new file mode 100644 index 0000000..0900660 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/common.rb @@ -0,0 +1,697 @@ +#frozen_string_literal: false +require 'json/version' +require 'json/generic_object' + +module JSON + NOT_SET = Object.new.freeze + private_constant :NOT_SET + + class << self + # :call-seq: + # JSON[object] -> new_array or new_string + # + # If +object+ is a \String, + # calls JSON.parse with +object+ and +opts+ (see method #parse): + # json = '[0, 1, null]' + # JSON[json]# => [0, 1, nil] + # + # Otherwise, calls JSON.generate with +object+ and +opts+ (see method #generate): + # ruby = [0, 1, nil] + # JSON[ruby] # => '[0,1,null]' + def [](object, opts = {}) + if object.respond_to? :to_str + JSON.parse(object.to_str, opts) + else + JSON.generate(object, opts) + end + end + + # Returns the JSON parser class that is used by JSON. This is either + # JSON::Ext::Parser or JSON::Pure::Parser: + # JSON.parser # => JSON::Ext::Parser + attr_reader :parser + + # Set the JSON parser class _parser_ to be used by JSON. + def parser=(parser) # :nodoc: + @parser = parser + remove_const :Parser if const_defined?(:Parser, false) + const_set :Parser, parser + end + + # Return the constant located at _path_. The format of _path_ has to be + # either ::A::B::C or A::B::C. In any case, A has to be located at the top + # level (absolute namespace path?). If there doesn't exist a constant at + # the given path, an ArgumentError is raised. + def deep_const_get(path) # :nodoc: + path.to_s.split(/::/).inject(Object) do |p, c| + case + when c.empty? then p + when p.const_defined?(c, true) then p.const_get(c) + else + begin + p.const_missing(c) + rescue NameError => e + raise ArgumentError, "can't get const #{path}: #{e}" + end + end + end + end + + # Set the module _generator_ to be used by JSON. + def generator=(generator) # :nodoc: + old, $VERBOSE = $VERBOSE, nil + @generator = generator + generator_methods = generator::GeneratorMethods + for const in generator_methods.constants + klass = deep_const_get(const) + modul = generator_methods.const_get(const) + klass.class_eval do + instance_methods(false).each do |m| + m.to_s == 'to_json' and remove_method m + end + include modul + end + end + self.state = generator::State + const_set :State, self.state + const_set :SAFE_STATE_PROTOTYPE, State.new # for JRuby + const_set :FAST_STATE_PROTOTYPE, create_fast_state + const_set :PRETTY_STATE_PROTOTYPE, create_pretty_state + ensure + $VERBOSE = old + end + + def create_fast_state + State.new( + :indent => '', + :space => '', + :object_nl => "", + :array_nl => "", + :max_nesting => false + ) + end + + def create_pretty_state + State.new( + :indent => ' ', + :space => ' ', + :object_nl => "\n", + :array_nl => "\n" + ) + end + + # Returns the JSON generator module that is used by JSON. This is + # either JSON::Ext::Generator or JSON::Pure::Generator: + # JSON.generator # => JSON::Ext::Generator + attr_reader :generator + + # Sets or Returns the JSON generator state class that is used by JSON. This is + # either JSON::Ext::Generator::State or JSON::Pure::Generator::State: + # JSON.state # => JSON::Ext::Generator::State + attr_accessor :state + end + + DEFAULT_CREATE_ID = 'json_class'.freeze + private_constant :DEFAULT_CREATE_ID + + CREATE_ID_TLS_KEY = "JSON.create_id".freeze + private_constant :CREATE_ID_TLS_KEY + + # Sets create identifier, which is used to decide if the _json_create_ + # hook of a class should be called; initial value is +json_class+: + # JSON.create_id # => 'json_class' + def self.create_id=(new_value) + Thread.current[CREATE_ID_TLS_KEY] = new_value.dup.freeze + end + + # Returns the current create identifier. + # See also JSON.create_id=. + def self.create_id + Thread.current[CREATE_ID_TLS_KEY] || DEFAULT_CREATE_ID + end + + NaN = 0.0/0 + + Infinity = 1.0/0 + + MinusInfinity = -Infinity + + # The base exception for JSON errors. + class JSONError < StandardError + def self.wrap(exception) + obj = new("Wrapped(#{exception.class}): #{exception.message.inspect}") + obj.set_backtrace exception.backtrace + obj + end + end + + # This exception is raised if a parser error occurs. + class ParserError < JSONError; end + + # This exception is raised if the nesting of parsed data structures is too + # deep. + class NestingError < ParserError; end + + # :stopdoc: + class CircularDatastructure < NestingError; end + # :startdoc: + + # This exception is raised if a generator or unparser error occurs. + class GeneratorError < JSONError; end + # For backwards compatibility + UnparserError = GeneratorError # :nodoc: + + # This exception is raised if the required unicode support is missing on the + # system. Usually this means that the iconv library is not installed. + class MissingUnicodeSupport < JSONError; end + + module_function + + # :call-seq: + # JSON.parse(source, opts) -> object + # + # Returns the Ruby objects created by parsing the given +source+. + # + # Argument +source+ contains the \String to be parsed. + # + # Argument +opts+, if given, contains a \Hash of options for the parsing. + # See {Parsing Options}[#module-JSON-label-Parsing+Options]. + # + # --- + # + # When +source+ is a \JSON array, returns a Ruby \Array: + # source = '["foo", 1.0, true, false, null]' + # ruby = JSON.parse(source) + # ruby # => ["foo", 1.0, true, false, nil] + # ruby.class # => Array + # + # When +source+ is a \JSON object, returns a Ruby \Hash: + # source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}' + # ruby = JSON.parse(source) + # ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil} + # ruby.class # => Hash + # + # For examples of parsing for all \JSON data types, see + # {Parsing \JSON}[#module-JSON-label-Parsing+JSON]. + # + # Parses nested JSON objects: + # source = <<-EOT + # { + # "name": "Dave", + # "age" :40, + # "hats": [ + # "Cattleman's", + # "Panama", + # "Tophat" + # ] + # } + # EOT + # ruby = JSON.parse(source) + # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # --- + # + # Raises an exception if +source+ is not valid JSON: + # # Raises JSON::ParserError (783: unexpected token at ''): + # JSON.parse('') + # + def parse(source, opts = {}) + Parser.new(source, **(opts||{})).parse + end + + # :call-seq: + # JSON.parse!(source, opts) -> object + # + # Calls + # parse(source, opts) + # with +source+ and possibly modified +opts+. + # + # Differences from JSON.parse: + # - Option +max_nesting+, if not provided, defaults to +false+, + # which disables checking for nesting depth. + # - Option +allow_nan+, if not provided, defaults to +true+. + def parse!(source, opts = {}) + opts = { + :max_nesting => false, + :allow_nan => true + }.merge(opts) + Parser.new(source, **(opts||{})).parse + end + + # :call-seq: + # JSON.load_file(path, opts={}) -> object + # + # Calls: + # parse(File.read(path), opts) + # + # See method #parse. + def load_file(filespec, opts = {}) + parse(File.read(filespec), opts) + end + + # :call-seq: + # JSON.load_file!(path, opts = {}) + # + # Calls: + # JSON.parse!(File.read(path, opts)) + # + # See method #parse! + def load_file!(filespec, opts = {}) + parse!(File.read(filespec), opts) + end + + # :call-seq: + # JSON.generate(obj, opts = nil) -> new_string + # + # Returns a \String containing the generated \JSON data. + # + # See also JSON.fast_generate, JSON.pretty_generate. + # + # Argument +obj+ is the Ruby object to be converted to \JSON. + # + # Argument +opts+, if given, contains a \Hash of options for the generation. + # See {Generating Options}[#module-JSON-label-Generating+Options]. + # + # --- + # + # When +obj+ is an \Array, returns a \String containing a \JSON array: + # obj = ["foo", 1.0, true, false, nil] + # json = JSON.generate(obj) + # json # => '["foo",1.0,true,false,null]' + # + # When +obj+ is a \Hash, returns a \String containing a \JSON object: + # obj = {foo: 0, bar: 's', baz: :bat} + # json = JSON.generate(obj) + # json # => '{"foo":0,"bar":"s","baz":"bat"}' + # + # For examples of generating from other Ruby objects, see + # {Generating \JSON from Other Objects}[#module-JSON-label-Generating+JSON+from+Other+Objects]. + # + # --- + # + # Raises an exception if any formatting option is not a \String. + # + # Raises an exception if +obj+ contains circular references: + # a = []; b = []; a.push(b); b.push(a) + # # Raises JSON::NestingError (nesting of 100 is too deep): + # JSON.generate(a) + # + def generate(obj, opts = nil) + if State === opts + state = opts + else + state = State.new(opts) + end + state.generate(obj) + end + + # :stopdoc: + # I want to deprecate these later, so I'll first be silent about them, and + # later delete them. + alias unparse generate + module_function :unparse + # :startdoc: + + # :call-seq: + # JSON.fast_generate(obj, opts) -> new_string + # + # Arguments +obj+ and +opts+ here are the same as + # arguments +obj+ and +opts+ in JSON.generate. + # + # By default, generates \JSON data without checking + # for circular references in +obj+ (option +max_nesting+ set to +false+, disabled). + # + # Raises an exception if +obj+ contains circular references: + # a = []; b = []; a.push(b); b.push(a) + # # Raises SystemStackError (stack level too deep): + # JSON.fast_generate(a) + def fast_generate(obj, opts = nil) + if State === opts + state = opts + else + state = JSON.create_fast_state.configure(opts) + end + state.generate(obj) + end + + # :stopdoc: + # I want to deprecate these later, so I'll first be silent about them, and later delete them. + alias fast_unparse fast_generate + module_function :fast_unparse + # :startdoc: + + # :call-seq: + # JSON.pretty_generate(obj, opts = nil) -> new_string + # + # Arguments +obj+ and +opts+ here are the same as + # arguments +obj+ and +opts+ in JSON.generate. + # + # Default options are: + # { + # indent: ' ', # Two spaces + # space: ' ', # One space + # array_nl: "\n", # Newline + # object_nl: "\n" # Newline + # } + # + # Example: + # obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}} + # json = JSON.pretty_generate(obj) + # puts json + # Output: + # { + # "foo": [ + # "bar", + # "baz" + # ], + # "bat": { + # "bam": 0, + # "bad": 1 + # } + # } + # + def pretty_generate(obj, opts = nil) + if State === opts + state, opts = opts, nil + else + state = JSON.create_pretty_state + end + if opts + if opts.respond_to? :to_hash + opts = opts.to_hash + elsif opts.respond_to? :to_h + opts = opts.to_h + else + raise TypeError, "can't convert #{opts.class} into Hash" + end + state.configure(opts) + end + state.generate(obj) + end + + # :stopdoc: + # I want to deprecate these later, so I'll first be silent about them, and later delete them. + alias pretty_unparse pretty_generate + module_function :pretty_unparse + # :startdoc: + + class << self + # Sets or returns default options for the JSON.load method. + # Initially: + # opts = JSON.load_default_options + # opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true} + attr_accessor :load_default_options + end + self.load_default_options = { + :max_nesting => false, + :allow_nan => true, + :allow_blank => true, + :create_additions => true, + } + + # :call-seq: + # JSON.load(source, proc = nil, options = {}) -> object + # + # Returns the Ruby objects created by parsing the given +source+. + # + # - Argument +source+ must be, or be convertible to, a \String: + # - If +source+ responds to instance method +to_str+, + # source.to_str becomes the source. + # - If +source+ responds to instance method +to_io+, + # source.to_io.read becomes the source. + # - If +source+ responds to instance method +read+, + # source.read becomes the source. + # - If both of the following are true, source becomes the \String 'null': + # - Option +allow_blank+ specifies a truthy value. + # - The source, as defined above, is +nil+ or the empty \String ''. + # - Otherwise, +source+ remains the source. + # - Argument +proc+, if given, must be a \Proc that accepts one argument. + # It will be called recursively with each result (depth-first order). + # See details below. + # BEWARE: This method is meant to serialise data from trusted user input, + # like from your own database server or clients under your control, it could + # be dangerous to allow untrusted users to pass JSON sources into it. + # - Argument +opts+, if given, contains a \Hash of options for the parsing. + # See {Parsing Options}[#module-JSON-label-Parsing+Options]. + # The default options can be changed via method JSON.load_default_options=. + # + # --- + # + # When no +proc+ is given, modifies +source+ as above and returns the result of + # parse(source, opts); see #parse. + # + # Source for following examples: + # source = <<-EOT + # { + # "name": "Dave", + # "age" :40, + # "hats": [ + # "Cattleman's", + # "Panama", + # "Tophat" + # ] + # } + # EOT + # + # Load a \String: + # ruby = JSON.load(source) + # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # Load an \IO object: + # require 'stringio' + # object = JSON.load(StringIO.new(source)) + # object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # Load a \File object: + # path = 't.json' + # File.write(path, source) + # File.open(path) do |file| + # JSON.load(file) + # end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # --- + # + # When +proc+ is given: + # - Modifies +source+ as above. + # - Gets the +result+ from calling parse(source, opts). + # - Recursively calls proc(result). + # - Returns the final result. + # + # Example: + # require 'json' + # + # # Some classes for the example. + # class Base + # def initialize(attributes) + # @attributes = attributes + # end + # end + # class User < Base; end + # class Account < Base; end + # class Admin < Base; end + # # The JSON source. + # json = <<-EOF + # { + # "users": [ + # {"type": "User", "username": "jane", "email": "jane@example.com"}, + # {"type": "User", "username": "john", "email": "john@example.com"} + # ], + # "accounts": [ + # {"account": {"type": "Account", "paid": true, "account_id": "1234"}}, + # {"account": {"type": "Account", "paid": false, "account_id": "1235"}} + # ], + # "admins": {"type": "Admin", "password": "0wn3d"} + # } + # EOF + # # Deserializer method. + # def deserialize_obj(obj, safe_types = %w(User Account Admin)) + # type = obj.is_a?(Hash) && obj["type"] + # safe_types.include?(type) ? Object.const_get(type).new(obj) : obj + # end + # # Call to JSON.load + # ruby = JSON.load(json, proc {|obj| + # case obj + # when Hash + # obj.each {|k, v| obj[k] = deserialize_obj v } + # when Array + # obj.map! {|v| deserialize_obj v } + # end + # }) + # pp ruby + # Output: + # {"users"=> + # [#"User", "username"=>"jane", "email"=>"jane@example.com"}>, + # #"User", "username"=>"john", "email"=>"john@example.com"}>], + # "accounts"=> + # [{"account"=> + # #"Account", "paid"=>true, "account_id"=>"1234"}>}, + # {"account"=> + # #"Account", "paid"=>false, "account_id"=>"1235"}>}], + # "admins"=> + # #"Admin", "password"=>"0wn3d"}>} + # + def load(source, proc = nil, options = {}) + opts = load_default_options.merge options + if source.respond_to? :to_str + source = source.to_str + elsif source.respond_to? :to_io + source = source.to_io.read + elsif source.respond_to?(:read) + source = source.read + end + if opts[:allow_blank] && (source.nil? || source.empty?) + source = 'null' + end + result = parse(source, opts) + recurse_proc(result, &proc) if proc + result + end + + # Recursively calls passed _Proc_ if the parsed data structure is an _Array_ or _Hash_ + def recurse_proc(result, &proc) # :nodoc: + case result + when Array + result.each { |x| recurse_proc x, &proc } + proc.call result + when Hash + result.each { |x, y| recurse_proc x, &proc; recurse_proc y, &proc } + proc.call result + else + proc.call result + end + end + + alias restore load + module_function :restore + + class << self + # Sets or returns the default options for the JSON.dump method. + # Initially: + # opts = JSON.dump_default_options + # opts # => {:max_nesting=>false, :allow_nan=>true, :script_safe=>false} + attr_accessor :dump_default_options + end + self.dump_default_options = { + :max_nesting => false, + :allow_nan => true, + :script_safe => false, + } + + # :call-seq: + # JSON.dump(obj, io = nil, limit = nil) + # + # Dumps +obj+ as a \JSON string, i.e. calls generate on the object and returns the result. + # + # The default options can be changed via method JSON.dump_default_options. + # + # - Argument +io+, if given, should respond to method +write+; + # the \JSON \String is written to +io+, and +io+ is returned. + # If +io+ is not given, the \JSON \String is returned. + # - Argument +limit+, if given, is passed to JSON.generate as option +max_nesting+. + # + # --- + # + # When argument +io+ is not given, returns the \JSON \String generated from +obj+: + # obj = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad} + # json = JSON.dump(obj) + # json # => "{\"foo\":[0,1],\"bar\":{\"baz\":2,\"bat\":3},\"bam\":\"bad\"}" + # + # When argument +io+ is given, writes the \JSON \String to +io+ and returns +io+: + # path = 't.json' + # File.open(path, 'w') do |file| + # JSON.dump(obj, file) + # end # => # + # puts File.read(path) + # Output: + # {"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"} + def dump(obj, anIO = nil, limit = nil, kwargs = nil) + io_limit_opt = [anIO, limit, kwargs].compact + kwargs = io_limit_opt.pop if io_limit_opt.last.is_a?(Hash) + anIO, limit = io_limit_opt + if anIO.respond_to?(:to_io) + anIO = anIO.to_io + elsif limit.nil? && !anIO.respond_to?(:write) + anIO, limit = nil, anIO + end + opts = JSON.dump_default_options + opts = opts.merge(:max_nesting => limit) if limit + opts = merge_dump_options(opts, **kwargs) if kwargs + result = generate(obj, opts) + if anIO + anIO.write result + anIO + else + result + end + rescue JSON::NestingError + raise ArgumentError, "exceed depth limit" + end + + # Encodes string using String.encode. + def self.iconv(to, from, string) + string.encode(to, from) + end + + def merge_dump_options(opts, strict: NOT_SET) + opts = opts.merge(strict: strict) if NOT_SET != strict + opts + end + + class << self + private :merge_dump_options + end +end + +module ::Kernel + private + + # Outputs _objs_ to STDOUT as JSON strings in the shortest form, that is in + # one line. + def j(*objs) + objs.each do |obj| + puts JSON::generate(obj, :allow_nan => true, :max_nesting => false) + end + nil + end + + # Outputs _objs_ to STDOUT as JSON strings in a pretty format, with + # indentation and over many lines. + def jj(*objs) + objs.each do |obj| + puts JSON::pretty_generate(obj, :allow_nan => true, :max_nesting => false) + end + nil + end + + # If _object_ is string-like, parse the string and return the parsed result as + # a Ruby data structure. Otherwise, generate a JSON text from the Ruby data + # structure object and return it. + # + # The _opts_ argument is passed through to generate/parse respectively. See + # generate and parse for their documentation. + def JSON(object, *args) + if object.respond_to? :to_str + JSON.parse(object.to_str, args.first) + else + JSON.generate(object, args.first) + end + end +end + +# Extends any Class to include _json_creatable?_ method. +class ::Class + # Returns true if this class can be used to create an instance + # from a serialised JSON string. The class has to implement a class + # method _json_create_ that expects a hash as first parameter. The hash + # should include the required data. + def json_creatable? + respond_to?(:json_create) + end +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/ext.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/ext.rb new file mode 100644 index 0000000..7264a85 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/ext.rb @@ -0,0 +1,15 @@ +require 'json/common' + +module JSON + # This module holds all the modules/classes that implement JSON's + # functionality as C extensions. + module Ext + require 'json/ext/parser' + require 'json/ext/generator' + $DEBUG and warn "Using Ext extension for JSON." + JSON.parser = Parser + JSON.generator = Generator + end + + JSON_LOADED = true unless defined?(::JSON::JSON_LOADED) +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/generic_object.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/generic_object.rb new file mode 100644 index 0000000..108309d --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/generic_object.rb @@ -0,0 +1,71 @@ +#frozen_string_literal: false +require 'ostruct' + +module JSON + class GenericObject < OpenStruct + class << self + alias [] new + + def json_creatable? + @json_creatable + end + + attr_writer :json_creatable + + def json_create(data) + data = data.dup + data.delete JSON.create_id + self[data] + end + + def from_hash(object) + case + when object.respond_to?(:to_hash) + result = new + object.to_hash.each do |key, value| + result[key] = from_hash(value) + end + result + when object.respond_to?(:to_ary) + object.to_ary.map { |a| from_hash(a) } + else + object + end + end + + def load(source, proc = nil, opts = {}) + result = ::JSON.load(source, proc, opts.merge(:object_class => self)) + result.nil? ? new : result + end + + def dump(obj, *args) + ::JSON.dump(obj, *args) + end + end + self.json_creatable = false + + def to_hash + table + end + + def [](name) + __send__(name) + end unless method_defined?(:[]) + + def []=(name, value) + __send__("#{name}=", value) + end unless method_defined?(:[]=) + + def |(other) + self.class[other.to_hash.merge(to_hash)] + end + + def as_json(*) + { JSON.create_id => self.class.name }.merge to_hash + end + + def to_json(*a) + as_json.to_json(*a) + end + end +end diff --git a/games/FNaFB2/Ruby/gems/json-2.7.1/version.rb b/games/FNaFB2/Ruby/gems/json-2.7.1/version.rb new file mode 100644 index 0000000..b43ceec --- /dev/null +++ b/games/FNaFB2/Ruby/gems/json-2.7.1/version.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: false +module JSON + # JSON version + VERSION = '2.7.1' + VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: + VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: + VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: + VERSION_BUILD = VERSION_ARRAY[2] # :nodoc: +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/.codeclimate.yml b/games/FNaFB2/Ruby/gems/websocket-1.2.10/.codeclimate.yml new file mode 100644 index 0000000..50537db --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/.codeclimate.yml @@ -0,0 +1,17 @@ +--- +engines: + duplication: + enabled: true + config: + languages: + - ruby + fixme: + enabled: true + rubocop: + enabled: true + channel: rubocop-0-52 +ratings: + paths: + - "**.rb" +exclude_paths: +- spec/ diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/.github/workflows/publish.yml b/games/FNaFB2/Ruby/gems/websocket-1.2.10/.github/workflows/publish.yml new file mode 100644 index 0000000..945e1c3 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/.github/workflows/publish.yml @@ -0,0 +1,17 @@ +name: Publish Gem + +on: + push: + tags: + - v* + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Release Gem + uses: cadwallion/publish-rubygems-action@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}} diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/.github/workflows/test.yml b/games/FNaFB2/Ruby/gems/websocket-1.2.10/.github/workflows/test.yml new file mode 100644 index 0000000..2bbeb8c --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/.github/workflows/test.yml @@ -0,0 +1,61 @@ +name: Test + +on: + push: + branches: + - 'master' + pull_request: + branches: + - '*' + +jobs: + rubocop: + runs-on: ubuntu-latest + name: Rubocop + steps: + - uses: actions/checkout@v2 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.0' + + - name: Install gems + run: bundle install + + - name: Run Rubocop + run: bundle exec rubocop + + test: + strategy: + fail-fast: false + matrix: + ruby: + - 2.1 + - 2.3 + - 2.4 + - 2.5 + - 2.6 + - 2.7 + - "3.0" + - 3.1 + - 3.2 + - 3.3 + - jruby + + runs-on: ubuntu-latest + name: Ruby ${{ matrix.ruby }} + + steps: + - uses: actions/checkout@v2 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + + - name: Install gems + run: bundle install + + - name: Run tests + run: bundle exec rspec diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/.gitignore b/games/FNaFB2/Ruby/gems/websocket-1.2.10/.gitignore new file mode 100644 index 0000000..99c9252 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/.gitignore @@ -0,0 +1,3 @@ +Gemfile.lock +autobahn +pkg/*.gem diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/.rubocop.yml b/games/FNaFB2/Ruby/gems/websocket-1.2.10/.rubocop.yml new file mode 100644 index 0000000..41b26b5 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/.rubocop.yml @@ -0,0 +1,69 @@ +require: rubocop-rspec + +AllCops: + DisplayCopNames: true + TargetRubyVersion: 2.1 + +# New version of Rubocop does not support 2.0 +Gemspec/RequiredRubyVersion: + Enabled: false + +Layout/IndentHeredoc: + Enabled: false + +# Target: 15 +Metrics/AbcSize: + Max: 24 + Exclude: + - lib/websocket/frame/handler/handler75.rb + - spec/**/* + +Metrics/BlockLength: + Exclude: + - spec/**/* + +Metrics/ClassLength: + Enabled: false + +# Target: 6 +Metrics/CyclomaticComplexity: + Max: 11 + Exclude: + - spec/support/handshake_requests.rb + +Metrics/LineLength: + Enabled: false + +# Target: 10 +Metrics/MethodLength: + Max: 18 + Exclude: + - lib/websocket/frame/handler/handler75.rb + +# Target: 7 +Metrics/PerceivedComplexity: + Max: 8 + Exclude: + - lib/websocket/frame/handler/handler75.rb + - spec/support/handshake_requests.rb + +RSpec/ContextWording: + Enabled: false + +RSpec/DescribeClass: + Enabled: false + +RSpec/ExampleLength: + Enabled: false + +RSpec/InstanceVariable: + Enabled: false + +RSpec/MultipleExpectations: + Enabled: false + +RSpec/NamedSubject: + Enabled: false + +Style/Documentation: + Enabled: false diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/CHANGELOG.md b/games/FNaFB2/Ruby/gems/websocket-1.2.10/CHANGELOG.md new file mode 100644 index 0000000..d9d8b19 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/CHANGELOG.md @@ -0,0 +1,121 @@ +# Changelog + +## Edge + +## 1.2.10 + +- ensure correct port is always specified for handshake +- no longer using Base64 for compatibility with Ruby 3.4+ + +## 1.2.9 + +- avoid ruby -w warnings + +## 1.2.8 + +- restore support for Ruby 2.0+ + +## 1.2.7 + +- fix bug in previous version for Ruby 2.3 + +## 1.2.6 + +- duplicate variables passed in initializers to avoid changing them + +## 1.2.5 + +- make handshake server resilient to non-string Rack env keys + +## 1.2.4 + +- add subprotocol handling for both server and client + +## 1.2.3 + +- fix for draft 76 when challenge might sometimes fail +- multiple small optimizations + +## 1.2.2 + +- fix handshake for draft 11+ sending Sec-WebSocket-Origin instead of Origin + +## 1.2.1 + +- fix error for draft 76 when leftovers are empty + +## 1.2.0 + +- Remove support for Ruby 1.8 +- Add support for sending custom headers for Client +- Better detection and handling of draft 76 +- Multiple small fixes and optimizations + +## 1.1.4 + +- verify valid close codes according to spec +- return error on invalid UTF-8 payload +- expose error message + +## 1.1.3 + +- fix close code support + +## 1.1.2 + +- fix support for rack input that is blocking (i.e. Passenger) + +## 1.1.1 + +- fix handling close code for frames version 5+ + +## 1.1.0 + +- allow raising ruby errors instead of setting `error` flag +- allow access to handshake headers +- add from_rack method +- add from_hash method +- stop extending handlers - it should improve performance for opening connection + +## 1.0.7 + +- fix requiring url under Ruby 1.9.1 +- support for Ruby 2.0.0 + +## 1.0.6 + +- support text frame types instead of only symbol ones +- support for sending masked frames + +## 1.0.5 + +- add support for close codes + +## 1.0.4 + +- nicer inspect - handful during debugging + +## 1.0.3 + +- improve pure ruby implementation performance by ~30% +- add support for native extension + +## 1.0.2 + +- allow configuration of max frame size via WebSocket.max_frame_size option +- much better documentation +- remove handler-specific methods from public list +- refactor code for easier use +- make parsers return more consistent values +- fix server handshake #to_s when no version was found +- add #uri to server handshake + +## 1.0.1 + +- allow creating client with :uri and :url options +- prevent strange results when header is mailformed +- set client path to '/' when :uri option is provided but without trailing slash + +## 1.0.0 + +- initial release diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/Gemfile b/games/FNaFB2/Ruby/gems/websocket-1.2.10/Gemfile new file mode 100644 index 0000000..c49be77 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/Gemfile @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +source 'http://rubygems.org' + +group :development do + gem 'rake' + gem 'rspec', '~> 3.7' + gem 'webrick' + + # Use same version as Code Climate for consistency with CI + # https://github.com/codeclimate/codeclimate-rubocop/blob/master/Gemfile.lock + gem 'rubocop', '0.52.1', require: false + gem 'rubocop-rspec', '1.21.0', require: false +end + +gemspec diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/README.md b/games/FNaFB2/Ruby/gems/websocket-1.2.10/README.md new file mode 100644 index 0000000..e030ca3 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/README.md @@ -0,0 +1,138 @@ +# WebSocket Ruby + +Universal Ruby library to handle WebSocket protocol. It focuses on providing abstraction layer over [WebSocket API](http://dev.w3.org/html5/websockets/) instead of providing server or client functionality. + +[![Gem Version](https://badge.fury.io/rb/websocket.svg)](http://badge.fury.io/rb/websocket) +[![Gem Downloads](https://img.shields.io/gem/dt/websocket.svg?maxAge=2592000)](https://rubygems.org/gems/websocket) +[![Code Climate](https://codeclimate.com/github/imanel/websocket-ruby.svg)](https://codeclimate.com/github/imanel/websocket-ruby) + +**Autobahn tests:** [server](http://imanel.github.com/websocket-ruby/autobahn/server/), [client](http://imanel.github.com/websocket-ruby/autobahn/client/) + +Currently WebSocket Ruby supports all existing drafts of WebSocket, which include: + +- [hixie-75](http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75) +- [hixie-76](http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76) +- [all hybi drafts (00-13)](http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17) +- [RFC 6455](http://datatracker.ietf.org/doc/rfc6455/) + +## Installation + +WebSocket Ruby has no external dependencies, so it can be installed from source or directly from rubygems: + +``` +gem install "websocket" +``` + +or via Gemfile: + +``` +gem "websocket" +``` + +## Server handshake + +``` ruby +@handshake = WebSocket::Handshake::Server.new + +# Parse client request +@handshake << < 'SESSIONID=1234' }) + +# Create request +@handshake.to_s # GET /demo HTTP/1.1 + # Upgrade: websocket + # Connection: Upgrade + # Host: example.com + # Cookie: SESSIONID=1234 + # Origin: http://example.com + # Sec-WebSocket-Version: 13 + # Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== + +# Parse server response +@handshake << < e + raise unless e.message =~ /websocket-native/ +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/error.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/error.rb new file mode 100644 index 0000000..ec63e9f --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/error.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +module WebSocket + class Error < RuntimeError + class Frame < ::WebSocket::Error + class ControlFramePayloadTooLong < ::WebSocket::Error::Frame + def message + :control_frame_payload_too_long + end + end + + class DataFrameInsteadContinuation < ::WebSocket::Error::Frame + def message + :data_frame_instead_continuation + end + end + + class FragmentedControlFrame < ::WebSocket::Error::Frame + def message + :fragmented_control_frame + end + end + + class Invalid < ::WebSocket::Error::Frame + def message + :invalid_frame + end + end + + class InvalidPayloadEncoding < ::WebSocket::Error::Frame + def message + :invalid_payload_encoding + end + end + + class MaskTooShort < ::WebSocket::Error::Frame + def message + :mask_is_too_short + end + end + + class ReservedBitUsed < ::WebSocket::Error::Frame + def message + :reserved_bit_used + end + end + + class TooLong < ::WebSocket::Error::Frame + def message + :frame_too_long + end + end + + class UnexpectedContinuationFrame < ::WebSocket::Error::Frame + def message + :unexpected_continuation_frame + end + end + + class UnknownFrameType < ::WebSocket::Error::Frame + def message + :unknown_frame_type + end + end + + class UnknownOpcode < ::WebSocket::Error::Frame + def message + :unknown_opcode + end + end + + class UnknownCloseCode < ::WebSocket::Error::Frame + def message + :unknown_close_code + end + end + + class UnknownVersion < ::WebSocket::Error::Frame + def message + :unknown_protocol_version + end + end + end + + class Handshake < ::WebSocket::Error + class GetRequestRequired < ::WebSocket::Error::Handshake + def message + :get_request_required + end + end + + class InvalidAuthentication < ::WebSocket::Error::Handshake + def message + :invalid_handshake_authentication + end + end + + class InvalidHeader < ::WebSocket::Error::Handshake + def message + :invalid_header + end + end + + class UnsupportedProtocol < ::WebSocket::Error::Handshake + def message + :unsupported_protocol + end + end + + class InvalidStatusCode < ::WebSocket::Error::Handshake + def message + :invalid_status_code + end + end + + class NoHostProvided < ::WebSocket::Error::Handshake + def message + :no_host_provided + end + end + + class UnknownVersion < ::WebSocket::Error::Handshake + def message + :unknown_protocol_version + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/exception_handler.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/exception_handler.rb new file mode 100644 index 0000000..6c2c57e --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/exception_handler.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module WebSocket + module ExceptionHandler + attr_accessor :error + + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods + # Rescue from WebSocket::Error errors. + # + # @param [String] method_name Name of method that should be wrapped and rescued + # @param [Hash] options Options for rescue + # + # @option options [Any] :return Value that should be returned instead of raised error + def rescue_method(method_name, options = {}) + define_method "#{method_name}_with_rescue" do |*args| + begin + send("#{method_name}_without_rescue", *args) + rescue WebSocket::Error => e + self.error = e.message.to_sym + WebSocket.should_raise ? raise : options[:return] + end + end + alias_method "#{method_name}_without_rescue", method_name + alias_method method_name, "#{method_name}_with_rescue" + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame.rb new file mode 100644 index 0000000..f8b8009 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module WebSocket + module Frame + autoload :Base, "#{::WebSocket::ROOT}/websocket/frame/base" + autoload :Data, "#{::WebSocket::ROOT}/websocket/frame/data" + autoload :Handler, "#{::WebSocket::ROOT}/websocket/frame/handler" + autoload :Incoming, "#{::WebSocket::ROOT}/websocket/frame/incoming" + autoload :Outgoing, "#{::WebSocket::ROOT}/websocket/frame/outgoing" + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/base.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/base.rb new file mode 100644 index 0000000..31e1d99 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/base.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +module WebSocket + module Frame + # @abstract Subclass and override to implement custom frames + class Base + include ExceptionHandler + include NiceInspect + + attr_reader :type, :version, :error + attr_accessor :data, :code + + # Initialize frame + # @param args [Hash] Arguments for frame + # @option args [String] :data default data for frame + # @option args [String] :type Type of frame - available types are "text", "binary", "ping", "pong" and "close"(support depends on draft version) + # @option args [Integer] :code Code for close frame. Supported by drafts > 05. + # @option args [Integer] :version Version of draft. Currently supported version are 75, 76 and 00-13. + def initialize(args = {}) + @type = args[:type].to_sym if args[:type] + @code = args[:code] + @data = Data.new(args[:data].to_s) + @version = args[:version] || DEFAULT_VERSION + @handler = nil + include_version + end + rescue_method :initialize + + # Check if some errors occured + # @return [Boolean] True if error is set + def error? + !@error.nil? + end + + # Is selected type supported for selected handler? + def support_type? + @handler.supported_frames.include?(@type) + end + + # Implement in submodules + def supported_frames + raise NotImplementedError + end + + private + + # Include set of methods for selected protocol version + # @return [Boolean] false if protocol number is unknown, otherwise true + def include_version + @handler = case @version + when 75..76 then Handler::Handler75.new(self) + when 0..2 then Handler::Handler75.new(self) + when 3 then Handler::Handler03.new(self) + when 4 then Handler::Handler04.new(self) + when 5..6 then Handler::Handler05.new(self) + when 7..13 then Handler::Handler07.new(self) + else raise WebSocket::Error::Frame::UnknownVersion + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/data.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/data.rb new file mode 100644 index 0000000..3c79940 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/data.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module WebSocket + module Frame + class Data < String + def initialize(*args) + super(*convert_args(args)) + @masking_key = nil + end + + def <<(*args) + super(*convert_args(args)) + end + + # Convert all arguments to ASCII-8BIT for easier traversing + def convert_args(args) + args.collect { |arg| arg.dup.force_encoding('ASCII-8BIT') } + end + + # Extract mask from 4 first bytes according to spec + def set_mask + raise WebSocket::Error::Frame::MaskTooShort if bytesize < 4 + @masking_key = self[0..3].bytes.to_a + end + + # Remove mask flag - it will still be present in payload + def unset_mask + @masking_key = nil + end + + # Extract `count` bytes starting from `start_index` and unmask it if needed. + def getbytes(start_index, count) + data = self[start_index, count] + data = mask(data.bytes.to_a, @masking_key).pack('C*') if @masking_key + data + end + + # Mask whole payload using mask key + def mask(payload, mask) + return mask_native(payload, mask) if respond_to?(:mask_native) + result = [] + payload.each_with_index do |byte, i| + result[i] = byte ^ mask[i % 4] + end + result + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler.rb new file mode 100644 index 0000000..c502a5c --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module WebSocket + module Frame + module Handler + autoload :Base, "#{::WebSocket::ROOT}/websocket/frame/handler/base" + + autoload :Handler03, "#{::WebSocket::ROOT}/websocket/frame/handler/handler03" + autoload :Handler04, "#{::WebSocket::ROOT}/websocket/frame/handler/handler04" + autoload :Handler05, "#{::WebSocket::ROOT}/websocket/frame/handler/handler05" + autoload :Handler07, "#{::WebSocket::ROOT}/websocket/frame/handler/handler07" + autoload :Handler75, "#{::WebSocket::ROOT}/websocket/frame/handler/handler75" + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/base.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/base.rb new file mode 100644 index 0000000..d4d9859 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/base.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module WebSocket + module Frame + module Handler + class Base + def initialize(frame) + @frame = frame + end + + # Convert data to raw frame ready to send to client + # @return [String] Encoded frame + def encode_frame + raise NotImplementedError + end + + # Convert raw data to decoded frame + # @return [WebSocket::Frame::Incoming] Frame if found, nil otherwise + def decode_frame + raise NotImplementedError + end + + private + + # Check if frame is one of control frames + # @param [Symbol] frame_type Frame type + # @return [Boolean] True if given frame type is control frame + def control_frame?(frame_type) + !%i[text binary continuation].include?(frame_type) + end + + # Check if frame is one of data frames + # @param [Symbol] frame_type Frame type + # @return [Boolean] True if given frame type is data frame + def data_frame?(frame_type) + %i[text binary].include?(frame_type) + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler03.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler03.rb new file mode 100644 index 0000000..16e01fb --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler03.rb @@ -0,0 +1,224 @@ +# encoding: binary +# frozen_string_literal: true + +require 'securerandom' + +module WebSocket + module Frame + module Handler + class Handler03 < Base + # Hash of frame names and it's opcodes + FRAME_TYPES = { + continuation: 0, + close: 1, + ping: 2, + pong: 3, + text: 4, + binary: 5 + }.freeze + + # Hash of frame opcodes and it's names + FRAME_TYPES_INVERSE = FRAME_TYPES.invert.freeze + + def initialize(frame) + super + @application_data_buffer = nil + end + + # @see WebSocket::Frame::Base#supported_frames + def supported_frames + %i[text binary close ping pong] + end + + # @see WebSocket::Frame::Handler::Base#encode_frame + def encode_frame + frame = if @frame.outgoing_masking? + masking_key = SecureRandom.random_bytes(4) + tmp_data = Data.new(masking_key + @frame.data) + tmp_data.set_mask + masking_key + tmp_data.getbytes(4, tmp_data.size) + else + @frame.data + end + + encode_header + frame + end + + # @see WebSocket::Frame::Handler::Base#decode_frame + def decode_frame + while @frame.data.size > 1 + valid_header, more, frame_type, mask, payload_length = decode_header + return unless valid_header + + application_data = decode_payload(payload_length, mask) + + if more + decode_continuation_frame(application_data, frame_type) + elsif frame_type == :continuation + return decode_finish_continuation_frame(application_data) + else + raise(WebSocket::Error::Frame::InvalidPayloadEncoding) if frame_type == :text && !application_data.valid_encoding? + return @frame.class.new(version: @frame.version, type: frame_type, data: application_data, decoded: true) + end + end + nil + end + + # Allow turning on or off masking + def masking? + false + end + + private + + # This allows flipping the more bit to fin for draft 04 + def fin + false + end + + # Convert frame type name to opcode + # @param [Symbol] frame_type Frame type name + # @return [Integer] opcode or nil + # @raise [WebSocket::Error] if frame opcode is not known + def type_to_opcode(frame_type) + FRAME_TYPES[frame_type] || raise(WebSocket::Error::Frame::UnknownFrameType) + end + + # Convert frame opcode to type name + # @param [Integer] opcode Opcode + # @return [Symbol] Frame type name or nil + # @raise [WebSocket::Error] if frame type name is not known + def opcode_to_type(opcode) + FRAME_TYPES_INVERSE[opcode] || raise(WebSocket::Error::Frame::UnknownOpcode) + end + + def encode_header + mask = @frame.outgoing_masking? ? 0b10000000 : 0b00000000 + + output = String.new('') + output << (type_to_opcode(@frame.type) | (fin ? 0b10000000 : 0b00000000)) # since more, rsv1-3 are 0 and 0x80 for Draft 4 + output << encode_payload_length(@frame.data.size, mask) + output + end + + def encode_payload_length(length, mask) + output = String.new('') + if length <= 125 + output << (length | mask) # since rsv4 is 0 + elsif length < 65_536 # write 2 byte length + output << (126 | mask) + output << [length].pack('n') + else # write 8 byte length + output << (127 | mask) + output << [length >> 32, length & 0xFFFFFFFF].pack('NN') + end + output + end + + def decode_header + more, frame_type = decode_first_byte + header_length, payload_length, mask = decode_second_byte(frame_type) + return unless header_length + + # Compute the expected frame length + frame_length = header_length + payload_length + frame_length += 4 if mask + + raise(WebSocket::Error::Frame::TooLong) if frame_length > WebSocket.max_frame_size + + # Check buffer size + return unless buffer_exists?(frame_length) # Buffer incomplete + + # Remove frame header + @frame.data.slice!(0...header_length) + + [true, more, frame_type, mask, payload_length] + end + + def buffer_exists?(buffer_number) + !@frame.data.getbyte(buffer_number - 1).nil? + end + + def decode_first_byte + first_byte = @frame.data.getbyte(0) + + raise(WebSocket::Error::Frame::ReservedBitUsed) if first_byte & 0b01110000 != 0b00000000 + + more = ((first_byte & 0b10000000) == 0b10000000) ^ fin + frame_type = opcode_to_type first_byte & 0b00001111 + + raise(WebSocket::Error::Frame::FragmentedControlFrame) if more && control_frame?(frame_type) + raise(WebSocket::Error::Frame::DataFrameInsteadContinuation) if data_frame?(frame_type) && !@application_data_buffer.nil? + + [more, frame_type] + end + + def decode_second_byte(frame_type) + second_byte = @frame.data.getbyte(1) + + mask = @frame.incoming_masking? && (second_byte & 0b10000000) == 0b10000000 + length = second_byte & 0b01111111 + + raise(WebSocket::Error::Frame::ControlFramePayloadTooLong) if length > 125 && control_frame?(frame_type) + + header_length, payload_length = decode_payload_length(length) + + [header_length, payload_length, mask] + end + + def decode_payload_length(length) + case length + when 127 # Length defined by 8 bytes + # Check buffer size + return unless buffer_exists?(10) # Buffer incomplete + + # Only using the last 4 bytes for now, till I work out how to + # unpack 8 bytes. I'm sure 4GB frames will do for now :) + [10, @frame.data.getbytes(6, 4).unpack('N').first] + when 126 # Length defined by 2 bytes + # Check buffer size + return unless buffer_exists?(4) # Buffer incomplete + + [4, @frame.data.getbytes(2, 2).unpack('n').first] + else + [2, length] + end + end + + def decode_payload(payload_length, mask) + pointer = 0 + + # Read application data (unmasked if required) + @frame.data.set_mask if mask + pointer += 4 if mask + payload = @frame.data.getbytes(pointer, payload_length) + payload.force_encoding('UTF-8') + pointer += payload_length + @frame.data.unset_mask if mask + + # Throw away data up to pointer + @frame.data.slice!(0...pointer) + + payload + end + + def decode_continuation_frame(application_data, frame_type) + @application_data_buffer ||= String.new('') + @application_data_buffer << application_data + @frame_type ||= frame_type + end + + def decode_finish_continuation_frame(application_data) + raise(WebSocket::Error::Frame::UnexpectedContinuationFrame) unless @frame_type + @application_data_buffer << application_data + # Test valid UTF-8 encoding + raise(WebSocket::Error::Frame::InvalidPayloadEncoding) if @frame_type == :text && !@application_data_buffer.valid_encoding? + message = @frame.class.new(version: @frame.version, type: @frame_type, data: @application_data_buffer, decoded: true) + @application_data_buffer = nil + @frame_type = nil + message + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler04.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler04.rb new file mode 100644 index 0000000..782a1a3 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler04.rb @@ -0,0 +1,18 @@ +# encoding: binary +# frozen_string_literal: true + +module WebSocket + module Frame + module Handler + class Handler04 < Handler03 + private + + # The only difference between draft 03 framing and draft 04 framing is + # that the MORE bit has been changed to a FIN bit + def fin + true + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler05.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler05.rb new file mode 100644 index 0000000..8b7546e --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler05.rb @@ -0,0 +1,15 @@ +# encoding: binary +# frozen_string_literal: true + +module WebSocket + module Frame + module Handler + class Handler05 < Handler04 + # Since handler 5 masking should be enabled by default + def masking? + true + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler07.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler07.rb new file mode 100644 index 0000000..0e2cffb --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler07.rb @@ -0,0 +1,78 @@ +# encoding: binary +# frozen_string_literal: true + +module WebSocket + module Frame + module Handler + class Handler07 < Handler05 + # Hash of frame names and it's opcodes + FRAME_TYPES = { + continuation: 0, + text: 1, + binary: 2, + close: 8, + ping: 9, + pong: 10 + }.freeze + + # Hash of frame opcodes and it's names + FRAME_TYPES_INVERSE = FRAME_TYPES.invert.freeze + + def encode_frame + if @frame.type == :close + code = @frame.code || 1000 + raise WebSocket::Error::Frame::UnknownCloseCode unless valid_code?(code) + @frame.data = Data.new([code].pack('n') + @frame.data.to_s) + @frame.code = nil + end + super + end + + def decode_frame + result = super + if close_code?(result) + code = result.data.slice!(0..1) + result.code = code.unpack('n').first + raise WebSocket::Error::Frame::UnknownCloseCode unless valid_code?(result.code) + raise WebSocket::Error::Frame::InvalidPayloadEncoding unless valid_encoding?(result.data) + end + result + end + + private + + def valid_code?(code) + [1000, 1001, 1002, 1003, 1007, 1008, 1009, 1010, 1011].include?(code) || (3000..4999).cover?(code) + end + + def valid_encoding?(data) + return true if data.nil? + data.encode('UTF-8') + true + rescue StandardError + false + end + + def close_code?(frame) + frame && frame.type == :close && !frame.data.empty? + end + + # Convert frame type name to opcode + # @param [Symbol] frame_type Frame type name + # @return [Integer] opcode or nil + # @raise [WebSocket::Error] if frame opcode is not known + def type_to_opcode(frame_type) + FRAME_TYPES[frame_type] || raise(WebSocket::Error::Frame::UnknownFrameType) + end + + # Convert frame opcode to type name + # @param [Integer] opcode Opcode + # @return [Symbol] Frame type name or nil + # @raise [WebSocket::Error] if frame type name is not known + def opcode_to_type(opcode) + FRAME_TYPES_INVERSE[opcode] || raise(WebSocket::Error::Frame::UnknownOpcode) + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler75.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler75.rb new file mode 100644 index 0000000..1c18796 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/handler/handler75.rb @@ -0,0 +1,78 @@ +# encoding: binary +# frozen_string_literal: true + +module WebSocket + module Frame + module Handler + class Handler75 < Base + # @see WebSocket::Frame::Base#supported_frames + def supported_frames + %i[text close] + end + + # @see WebSocket::Frame::Handler::Base#encode_frame + def encode_frame + case @frame.type + when :close then "\xff\x00" + when :text then + ary = ["\x00", @frame.data, "\xff"] + ary.map { |s| s.encode('UTF-8', 'UTF-8', invalid: :replace) } + ary.join + else raise WebSocket::Error::Frame::UnknownFrameType + end + end + + # @see WebSocket::Frame::Handler::Base#decode_frame + def decode_frame + return if @frame.data.size.zero? + + pointer = 0 + frame_type = @frame.data.getbyte(pointer) + pointer += 1 + + if (frame_type & 0x80) == 0x80 + # If the high-order bit of the /frame type/ byte is set + length = 0 + + loop do + return unless @frame.data.getbyte(pointer) + b = @frame.data.getbyte(pointer) + pointer += 1 + b_v = b & 0x7F + length = length * 128 + b_v + break unless (b & 0x80) == 0x80 + end + + raise WebSocket::Error::Frame::TooLong if length > ::WebSocket.max_frame_size + + unless @frame.data.getbyte(pointer + length - 1).nil? + # Straight from spec - I'm sure this isn't crazy... + # 6. Read /length/ bytes. + # 7. Discard the read bytes. + @frame.instance_variable_set '@data', @frame.data[(pointer + length)..-1] + + # If the /frame type/ is 0xFF and the /length/ was 0, then close + if length.zero? + @frame.class.new(version: @frame.version, type: :close, decoded: true) + end + end + else + # If the high-order bit of the /frame type/ byte is _not_ set + + raise WebSocket::Error::Frame::Invalid if @frame.data.getbyte(0) != 0x00 + + # Addition to the spec to protect against malicious requests + raise WebSocket::Error::Frame::TooLong if @frame.data.size > ::WebSocket.max_frame_size + + msg = @frame.data.slice!(/\A\x00[^\xff]*\xff/) + if msg + msg.gsub!(/\A\x00|\xff\z/, '') + msg.force_encoding('UTF-8') + @frame.class.new(version: @frame.version, type: :text, data: msg, decoded: true) + end + end + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/incoming.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/incoming.rb new file mode 100644 index 0000000..e824024 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/incoming.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module WebSocket + module Frame + # Construct or parse incoming WebSocket Frame. + # @note You should NEVER use this class directly - use Client or Server subclasses instead, as they contain additional frame options(i.e. Client-side masking in draft 04) + # + # @example + # frame = WebSocket::Frame::Incoming::Server.new(version: @handshake.version) + # frame << "\x81\x05\x48\x65\x6c\x6c\x6f\x81\x06\x77\x6f\x72\x6c\x64\x21" + # frame.next # "Hello" + # frame.next # "world!"" + class Incoming < Base + autoload :Client, "#{::WebSocket::ROOT}/websocket/frame/incoming/client" + autoload :Server, "#{::WebSocket::ROOT}/websocket/frame/incoming/server" + + def initialize(args = {}) + @decoded = args[:decoded] || false + super + end + + # If data is still encoded after receiving then this is false. After calling "next" you will receive + # another instance of incoming frame, but with data decoded - this function will return true and + # to_s will return frame content instead of raw data. + # @return [Boolean] If frame already decoded? + def decoded? + @decoded + end + + # Add provided string as raw incoming frame. + # @param data [String] Raw frame + def <<(data) + @data << data + end + + # Return next complete frame. + # This function will merge together splitted frames and return as combined content. + # Check #error if nil received to check for eventual parsing errors + # @return [WebSocket::Frame::Incoming] Single incoming frame or nil if no complete frame is available. + def next + @handler.decode_frame unless decoded? + end + rescue_method :next + + # If decoded then this will return frame content. Otherwise it will return raw frame. + # @return [String] Data of frame + def to_s + @data + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/incoming/client.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/incoming/client.rb new file mode 100644 index 0000000..a64ad2d --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/incoming/client.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module WebSocket + module Frame + class Incoming + class Client < Incoming + def incoming_masking? + false + end + + def outgoing_masking? + @handler.masking? + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/incoming/server.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/incoming/server.rb new file mode 100644 index 0000000..6cd8d77 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/incoming/server.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module WebSocket + module Frame + class Incoming + class Server < Incoming + def incoming_masking? + @handler.masking? + end + + def outgoing_masking? + false + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/outgoing.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/outgoing.rb new file mode 100644 index 0000000..d8fec13 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/outgoing.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module WebSocket + module Frame + # Construct or parse outgoing WebSocket Frame. + # @note You should NEVER use this class directly - use Client or Server subclasses instead, as they contain additional frame options(i.e. Client-side masking in draft 04) + # + # @example + # frame = WebSocket::Frame::Outgoing::Server.new(version: @handshake.version, data: "Hello", type: :text) + # frame.to_s # "\x81\x05\x48\x65\x6c\x6c\x6f" + class Outgoing < Base + autoload :Client, "#{::WebSocket::ROOT}/websocket/frame/outgoing/client" + autoload :Server, "#{::WebSocket::ROOT}/websocket/frame/outgoing/server" + + # Is selected type supported by current draft version? + # @return [Boolean] true if frame type is supported + def supported? + support_type? + end + + # Should current frame be sent? Exclude empty frames etc. + # @return [Boolean] true if frame should be sent + def require_sending? + !error? + end + + # Return raw frame formatted for sending. + def to_s + raise WebSocket::Error::Frame::UnknownFrameType unless supported? + @handler.encode_frame + end + rescue_method :to_s + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/outgoing/client.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/outgoing/client.rb new file mode 100644 index 0000000..fad72b8 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/outgoing/client.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module WebSocket + module Frame + class Outgoing + class Client < Outgoing + def incoming_masking? + false + end + + def outgoing_masking? + @handler.masking? + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/outgoing/server.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/outgoing/server.rb new file mode 100644 index 0000000..9e9d5b2 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/frame/outgoing/server.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module WebSocket + module Frame + class Outgoing + class Server < Outgoing + def incoming_masking? + @handler.masking? + end + + def outgoing_masking? + false + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/handshake.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/handshake.rb new file mode 100644 index 0000000..3e8c1f4 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/handshake.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module WebSocket + module Handshake + autoload :Base, "#{::WebSocket::ROOT}/websocket/handshake/base" + autoload :Client, "#{::WebSocket::ROOT}/websocket/handshake/client" + autoload :Handler, "#{::WebSocket::ROOT}/websocket/handshake/handler" + autoload :Server, "#{::WebSocket::ROOT}/websocket/handshake/server" + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/handshake/base.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/handshake/base.rb new file mode 100644 index 0000000..274b8fc --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/handshake/base.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: true + +module WebSocket + module Handshake + # @abstract Subclass and override to implement custom handshakes + class Base + include ExceptionHandler + include NiceInspect + + attr_reader :host, :path, :query, + :state, :version, :secure, + :headers, :protocols + + # Initialize new WebSocket Handshake and set it's state to :new + def initialize(args = {}) + args.each do |k, v| + value = begin + v.dup + rescue TypeError + v + end + instance_variable_set("@#{k}", value) + end + + @state = :new + @handler = nil + + @data = String.new('') + @headers ||= {} + @protocols ||= [] + end + + # @abstract Add data to handshake + def <<(data) + @data << data + end + + # Return textual representation of handshake request or response + # @return [String] text of response + def to_s + @handler ? @handler.to_s : '' + end + rescue_method :to_s, return: '' + + # Is parsing of data finished? + # @return [Boolena] True if request was completely parsed or error occured. False otherwise + def finished? + @state == :finished || @state == :error + end + + # Is parsed data valid? + # @return [Boolean] False if some errors occured. Reason for error could be found in error method + def valid? + finished? && @error.nil? && @handler && @handler.valid? + end + rescue_method :valid?, return: false + + # @abstract Should send data after parsing is finished? + def should_respond? + raise NotImplementedError + end + + # Data left from parsing. Sometimes data that doesn't belong to handshake are added - use this method to retrieve them. + # @return [String] String if some data are available. Nil otherwise + def leftovers + (@leftovers.to_s.split("\n", reserved_leftover_lines + 1)[reserved_leftover_lines] || '').strip + end + + # Return default port for protocol (80 for ws, 443 for wss) + def default_port + secure ? 443 : 80 + end + + # Check if provided port is a default one + def default_port? + port == default_port + end + + def port + @port || default_port + end + + # URI of request. + # @return [String] Full URI with protocol + # @example + # @handshake.uri #=> "ws://example.com/path?query=true" + def uri + uri = String.new(secure ? 'wss://' : 'ws://') + uri << host + uri << ":#{port}" unless default_port? + uri << path + uri << "?#{query}" if query + uri + end + + private + + # Number of lines after header that should be handled as belonging to handshake. Any data after those lines will be handled as leftovers. + # @return [Integer] Number of lines + def reserved_leftover_lines + 0 + end + + # Changes state to error and sets error message + # @param [String] message Error message to set + def error=(message) + @state = :error + super + end + + HEADER = /^([^:]+):\s*(.+)$/ + + # Parse data imported to handshake and sets state to finished if necessary. + # @return [Boolean] True if finished parsing. False if not all data received yet. + def parse_data + header, @leftovers = @data.split("\r\n\r\n", 2) + return false unless @leftovers # The whole header has not been received yet. + + lines = header.split("\r\n") + + first_line = lines.shift + parse_first_line(first_line) + + lines.each do |line| + h = HEADER.match(line) + next unless h # Skip any invalid headers + key = h[1].strip.downcase + val = h[2].strip + # If the header is already set and refers to the websocket protocol, append the new value + if @headers.key?(key) && key =~ /^(sec-)?websocket-protocol$/ + @headers[key] << ", #{val}" + else + @headers[key] = val + end + end + + @state = :finished + true + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/handshake/client.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/handshake/client.rb new file mode 100644 index 0000000..d1ae0e0 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/handshake/client.rb @@ -0,0 +1,130 @@ +# frozen_string_literal: true + +require 'uri' + +module WebSocket + module Handshake + # Construct or parse a client WebSocket handshake. + # + # @example + # @handshake = WebSocket::Handshake::Client.new(url: 'ws://example.com') + # + # # Create request + # @handshake.to_s # GET /demo HTTP/1.1 + # # Upgrade: websocket + # # Connection: Upgrade + # # Host: example.com + # # Origin: http://example.com + # # Sec-WebSocket-Version: 13 + # # Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== + # + # # Parse server response + # @handshake << <] :protocols An array of supported sub-protocols + # @option args [Integer] :version Version of WebSocket to use. Default: 13 (this is version from RFC) + # @option args [Hash] :headers HTTP headers to use in the handshake + # + # @example + # Websocket::Handshake::Client.new(url: "ws://example.com/path?query=true") + def initialize(args = {}) + super + + if @url || @uri + uri = URI.parse(@url || @uri) + @secure ||= (uri.scheme == 'wss') + @host ||= uri.host + @port ||= uri.port || default_port + @path ||= uri.path + @query ||= uri.query + end + + @path = '/' if @path.nil? || @path.empty? + @version ||= DEFAULT_VERSION + + raise WebSocket::Error::Handshake::NoHostProvided unless @host + + include_version + end + rescue_method :initialize + + # Add text of response from Server. This method will parse content immediately and update state and error(if neccessary) + # + # @param [String] data Data to add + # + # @example + # @handshake << < 2**32 - 1 + + quotient + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/handshake/server.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/handshake/server.rb new file mode 100644 index 0000000..109ccaa --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/handshake/server.rb @@ -0,0 +1,179 @@ +# frozen_string_literal: true + +module WebSocket + module Handshake + # Construct or parse a server WebSocket handshake. + # + # @example + # handshake = WebSocket::Handshake::Server.new + # + # # Parse client request + # @handshake << <] :protocols an array of supported sub-protocols + # + # @example + # Websocket::Handshake::Server.new(secure: true) + def initialize(args = {}) + super + @secure ||= false + end + + # Add text of request from Client. This method will parse content immediately and update version, state and error(if neccessary) + # + # @param [String] data Data to add + # + # @example + # @handshake << <" + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/version.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/version.rb new file mode 100644 index 0000000..a928beb --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/lib/websocket/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module WebSocket + VERSION = '1.2.10'.freeze +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_03_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_03_spec.rb new file mode 100644 index 0000000..78ee024 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_03_spec.rb @@ -0,0 +1,120 @@ +# encoding: binary +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Incoming frame draft 03' do + subject { frame } + + let(:version) { 3 } + let(:frame) { WebSocket::Frame::Incoming.new(version: version, data: encoded_text) } + let(:encoded_text) { nil } + let(:decoded_text) { nil } + let(:frame_type) { nil } + let(:error) { nil } + + it_behaves_like 'valid_incoming_frame' + + context 'should properly decode close frame' do + let(:encoded_text) { "\x01\x05" + decoded_text } + let(:frame_type) { :close } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode ping frame' do + let(:encoded_text) { "\x02\x05" + decoded_text } + let(:frame_type) { :ping } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode pong frame' do + let(:encoded_text) { "\x03\x05" + decoded_text } + let(:frame_type) { :pong } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode text frame' do + let(:encoded_text) { "\x04\x05" + decoded_text } + let(:decoded_text) { 'Hello' } + let(:frame_type) { :text } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode text frame with continuation' do + let(:encoded_text) { "\x84\x03Hel\x00\x02lo" } + let(:frame_type) { :text } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode text frame in between of continuation' do + let(:encoded_text) { "\x84\x03Hel\x03\x03abc\x00\x02lo" } + let(:frame_type) { %i[pong text] } + let(:decoded_text) { %w[abc Hello] } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should not return unfinished more frame' do + let(:encoded_text) { "\x84\x03Hel\x03\x03abc" } + let(:frame_type) { :pong } + let(:decoded_text) { 'abc' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode 256 bytes binary frame' do + let(:encoded_text) { "\x05\x7E\x01\x00" + decoded_text } + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 256 } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode 64KiB binary frame' do + let(:encoded_text) { "\x05\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text } + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 65_536 } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should wait with incomplete frame' do + let(:encoded_text) { "\x04\x06Hello" } + let(:decoded_text) { nil } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should raise error with invalid opcode' do + let(:encoded_text) { "\x09\x05Hello" } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::UnknownOpcode } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should raise error with too long frame' do + let(:encoded_text) { "\x04\x7F" + 'a' * WebSocket.max_frame_size } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::TooLong } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should raise error with continuation frame without more frame earlier' do + let(:encoded_text) { "\x00\x05Hello" } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::UnexpectedContinuationFrame } + + it_behaves_like 'valid_incoming_frame' + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_04_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_04_spec.rb new file mode 100644 index 0000000..781c5e5 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_04_spec.rb @@ -0,0 +1,120 @@ +# encoding: binary +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Incoming frame draft 04' do + subject { frame } + + let(:version) { 4 } + let(:frame) { WebSocket::Frame::Incoming.new(version: version, data: encoded_text) } + let(:encoded_text) { nil } + let(:decoded_text) { nil } + let(:frame_type) { nil } + let(:error) { nil } + + it_behaves_like 'valid_incoming_frame' + + context 'should properly decode close frame' do + let(:encoded_text) { "\x81\x05" + decoded_text } + let(:frame_type) { :close } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode ping frame' do + let(:encoded_text) { "\x82\x05" + decoded_text } + let(:frame_type) { :ping } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode pong frame' do + let(:encoded_text) { "\x83\x05" + decoded_text } + let(:frame_type) { :pong } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode text frame' do + let(:encoded_text) { "\x84\x05" + decoded_text } + let(:decoded_text) { 'Hello' } + let(:frame_type) { :text } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode text frame with continuation' do + let(:encoded_text) { "\x04\x03Hel\x80\x02lo" } + let(:frame_type) { :text } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode text frame in between of continuation' do + let(:encoded_text) { "\x04\x03Hel\x83\x03abc\x80\x02lo" } + let(:frame_type) { %i[pong text] } + let(:decoded_text) { %w[abc Hello] } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should not return unfinished more frame' do + let(:encoded_text) { "\x04\x03Hel\x83\x03abc" } + let(:frame_type) { :pong } + let(:decoded_text) { 'abc' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode 256 bytes binary frame' do + let(:encoded_text) { "\x85\x7E\x01\x00" + decoded_text } + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 256 } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode 64KiB binary frame' do + let(:encoded_text) { "\x85\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text } + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 65_536 } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should wait with incomplete frame' do + let(:encoded_text) { "\x84\x06Hello" } + let(:decoded_text) { nil } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should raise error with invalid opcode' do + let(:encoded_text) { "\x89\x05Hello" } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::UnknownOpcode } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should raise error with too long frame' do + let(:encoded_text) { "\x84\x7F" + 'a' * WebSocket.max_frame_size } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::TooLong } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should raise error with continuation frame without more frame earlier' do + let(:encoded_text) { "\x80\x05Hello" } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::UnexpectedContinuationFrame } + + it_behaves_like 'valid_incoming_frame' + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_05_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_05_spec.rb new file mode 100644 index 0000000..8aaa432 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_05_spec.rb @@ -0,0 +1,136 @@ +# encoding: binary +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Incoming frame draft 05' do + subject { frame } + + let(:version) { 5 } + let(:frame) { WebSocket::Frame::Incoming.new(version: version, data: encoded_text) } + let(:encoded_text) { nil } + let(:decoded_text) { nil } + let(:frame_type) { nil } + let(:error) { nil } + + it_behaves_like 'valid_incoming_frame' + + context 'should properly decode close frame' do + let(:encoded_text) { "\x81\x05" + decoded_text } + let(:frame_type) { :close } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode ping frame' do + let(:encoded_text) { "\x82\x05" + decoded_text } + let(:frame_type) { :ping } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode pong frame' do + let(:encoded_text) { "\x83\x05" + decoded_text } + let(:frame_type) { :pong } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode text frame' do + let(:encoded_text) { "\x84\x05" + decoded_text } + let(:decoded_text) { 'Hello' } + let(:frame_type) { :text } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode masked text frame' do + let(:encoded_text) { "\x84\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58" } + let(:decoded_text) { 'Hello' } + let(:frame_type) { :text } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode text frame with continuation' do + let(:encoded_text) { "\x04\x03Hel\x80\x02lo" } + let(:frame_type) { :text } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode masked text frame with continuation' do + let(:encoded_text) { "\x04\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x37\xfa\x21\x3d\x5b\x95" } + let(:frame_type) { :text } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode text frame in between of continuation' do + let(:encoded_text) { "\x04\x03Hel\x83\x03abc\x80\x02lo" } + let(:frame_type) { %i[pong text] } + let(:decoded_text) { %w[abc Hello] } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should not return unfinished more frame' do + let(:encoded_text) { "\x04\x03Hel\x83\x03abc" } + let(:frame_type) { :pong } + let(:decoded_text) { 'abc' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode 256 bytes binary frame' do + let(:encoded_text) { "\x85\x7E\x01\x00" + decoded_text } + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 256 } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode 64KiB binary frame' do + let(:encoded_text) { "\x85\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text } + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 65_536 } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should wait with incomplete frame' do + let(:encoded_text) { "\x84\x06Hello" } + let(:decoded_text) { nil } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should raise error with invalid opcode' do + let(:encoded_text) { "\x89\x05Hello" } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::UnknownOpcode } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should raise error with too long frame' do + let(:encoded_text) { "\x84\x7F" + 'a' * WebSocket.max_frame_size } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::TooLong } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should raise error with continuation frame without more frame earlier' do + let(:encoded_text) { "\x80\x05Hello" } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::UnexpectedContinuationFrame } + + it_behaves_like 'valid_incoming_frame' + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_07_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_07_spec.rb new file mode 100644 index 0000000..990fe09 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_07_spec.rb @@ -0,0 +1,153 @@ +# encoding: binary +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Incoming frame draft 07' do + subject { frame } + + let(:version) { 7 } + let(:frame) { WebSocket::Frame::Incoming.new(version: version, data: encoded_text) } + let(:encoded_text) { nil } + let(:decoded_text) { nil } + let(:frame_type) { nil } + let(:error) { nil } + + it_behaves_like 'valid_incoming_frame' + + context 'should properly decode close frame' do + let(:encoded_text) { "\x88\x07\x03\xE8" + decoded_text } + let(:frame_type) { :close } + let(:decoded_text) { 'Hello' } + let(:close_code) { 1000 } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should raise error with invalid close code' do + let(:encoded_text) { "\x88\x07\x03\xEDHello" } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::UnknownCloseCode } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode close frame with invalid UTF-8 message' do + let(:encoded_text) { "\x88\x03\x03\xE8\xE3" } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::InvalidPayloadEncoding } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode ping frame' do + let(:encoded_text) { "\x89\x05" + decoded_text } + let(:frame_type) { :ping } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode pong frame' do + let(:encoded_text) { "\x8a\x05" + decoded_text } + let(:frame_type) { :pong } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode text frame' do + let(:encoded_text) { "\x81\x05\x48\x65\x6c\x6c\x6f" } + let(:decoded_text) { 'Hello' } + let(:frame_type) { :text } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode masked text frame' do + let(:encoded_text) { "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58" } + let(:decoded_text) { 'Hello' } + let(:frame_type) { :text } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode text frame with continuation' do + let(:encoded_text) { "\x01\x03Hel\x80\x02lo" } + let(:frame_type) { :text } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode masked text frame with continuation' do + let(:encoded_text) { "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x37\xfa\x21\x3d\x5b\x95" } + let(:frame_type) { :text } + let(:decoded_text) { 'Hello' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode text frame in between of continuation' do + let(:encoded_text) { "\x01\x03Hel\x8a\x03abc\x80\x02lo" } + let(:frame_type) { %i[pong text] } + let(:decoded_text) { %w[abc Hello] } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should not return unfinished more frame' do + let(:encoded_text) { "\x01\x03Hel\x8a\x03abc" } + let(:frame_type) { :pong } + let(:decoded_text) { 'abc' } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode 256 bytes binary frame' do + let(:encoded_text) { "\x82\x7E\x01\x00" + decoded_text } + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 256 } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should properly decode 64KiB binary frame' do + let(:encoded_text) { "\x82\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text } + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 65_536 } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should wait with incomplete frame' do + let(:encoded_text) { "\x81\x06Hello" } + let(:decoded_text) { nil } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should raise error with invalid opcode' do + let(:encoded_text) { "\x85\x05Hello" } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::UnknownOpcode } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should raise error with too long frame' do + let(:encoded_text) { "\x81\x7F" + 'a' * WebSocket.max_frame_size } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::TooLong } + + it_behaves_like 'valid_incoming_frame' + end + + context 'should raise error with continuation frame without more frame earlier' do + let(:encoded_text) { "\x80\x05Hello" } + let(:decoded_text) { nil } + let(:error) { WebSocket::Error::Frame::UnexpectedContinuationFrame } + + it_behaves_like 'valid_incoming_frame' + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_75_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_75_spec.rb new file mode 100644 index 0000000..418616c --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_75_spec.rb @@ -0,0 +1,62 @@ +# encoding: binary +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Incoming frame draft 75' do + subject { frame } + + let(:version) { 75 } + let(:frame) { WebSocket::Frame::Incoming.new(version: version, data: encoded_text) } + let(:encoded_text) { nil } + let(:decoded_text) { nil } + let(:frame_type) { nil } + let(:error) { nil } + + it_behaves_like 'valid_incoming_frame' + + context 'with valid text frame' do + let(:encoded_text) { "\x00abc\xFF" } + let(:decoded_text) { 'abc' } + let(:frame_type) { :text } + + it_behaves_like 'valid_incoming_frame' + end + + context 'with two frames' do + let(:encoded_text) { "\x00abc\xFF\x00def\xFF" } + let(:decoded_text) { %w[abc def] } + let(:frame_type) { %i[text text] } + + it_behaves_like 'valid_incoming_frame' + end + + context 'with close frame' do + let(:encoded_text) { "\xFF\x00" } + let(:decoded_text) { '' } + let(:frame_type) { :close } + + it_behaves_like 'valid_incoming_frame' + end + + context 'with incomplete frame' do + let(:encoded_text) { "\x00test" } + let(:decoded_text) { nil } + + it_behaves_like 'valid_incoming_frame' + end + + context 'with invalid frame' do + let(:encoded_text) { 'invalid' } + let(:error) { WebSocket::Error::Frame::Invalid } + + it_behaves_like 'valid_incoming_frame' + end + + context 'with too long frame' do + let(:encoded_text) { "\x00" + 'a' * WebSocket.max_frame_size + "\xFF" } + let(:error) { WebSocket::Error::Frame::TooLong } + + it_behaves_like 'valid_incoming_frame' + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_common_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_common_spec.rb new file mode 100644 index 0000000..edf5e9e --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/incoming_common_spec.rb @@ -0,0 +1,32 @@ +# encoding: binary +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Incoming common frame' do + subject { WebSocket::Frame::Incoming.new } + + it 'is version 13' do + expect(subject.version).to be 13 + end + + it 'is not decoded' do + expect(subject.decoded?).to be false + end + + it 'has no errors' do + expect(subject.error?).to be false + end + + it 'allows adding data via <<' do + expect(subject.data).to eql '' + subject << 'test' + expect(subject.data).to eql 'test' + end + + it 'raises error on invalid version' do + subject = WebSocket::Frame::Incoming.new(version: 70) + expect(subject.error?).to be true + expect(subject.error).to be :unknown_protocol_version + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/masking_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/masking_spec.rb new file mode 100644 index 0000000..2d5263d --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/masking_spec.rb @@ -0,0 +1,18 @@ +# encoding: binary +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Masking frame draft 07' do + it 'encodes and decode masked frame correctly' do + outgoing_frame = WebSocket::Frame::Outgoing::Client.new(data: 'Hello World', type: 'text') + outgoing_frame.to_s + expect(outgoing_frame.error).to be_nil + incoming_frame = WebSocket::Frame::Incoming::Server.new(data: outgoing_frame.to_s).next + expect(incoming_frame).not_to be_nil + expect(incoming_frame.class).to eql(WebSocket::Frame::Incoming::Server) + expect(incoming_frame.error).to be_nil + expect(incoming_frame.decoded?).to be true + expect(incoming_frame.to_s).to eql('Hello World') + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_03_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_03_spec.rb new file mode 100644 index 0000000..e8394a4 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_03_spec.rb @@ -0,0 +1,81 @@ +# encoding: binary +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Outgoing frame draft 03' do + subject { frame } + + let(:version) { 3 } + let(:frame) { WebSocket::Frame::Outgoing.new(version: version, data: decoded_text, type: frame_type) } + let(:decoded_text) { '' } + let(:encoded_text) { "\x04\x00" } + let(:frame_type) { :text } + let(:require_sending) { true } + let(:error) { nil } + + it_behaves_like 'valid_outgoing_frame' + + context 'should properly encode close frame' do + let(:frame_type) { :close } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x01\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode ping frame' do + let(:frame_type) { :ping } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x02\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode pong frame' do + let(:frame_type) { :pong } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x03\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode text frame' do + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x04\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode 256 bytes binary frame' do + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 256 } + let(:encoded_text) { "\x05\x7E\x01\x00" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode 64KiB binary frame' do + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 65_536 } + let(:encoded_text) { "\x05\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should return error for unknown frame type' do + let(:frame_type) { :unknown } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { nil } + let(:error) { :unknown_frame_type } + let(:require_sending) { false } + + it_behaves_like 'valid_outgoing_frame' + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_04_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_04_spec.rb new file mode 100644 index 0000000..a1ef718 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_04_spec.rb @@ -0,0 +1,81 @@ +# encoding: binary +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Outgoing frame draft 04' do + subject { frame } + + let(:version) { 4 } + let(:frame) { WebSocket::Frame::Outgoing.new(version: version, data: decoded_text, type: frame_type) } + let(:decoded_text) { '' } + let(:encoded_text) { "\x84\x00" } + let(:frame_type) { :text } + let(:require_sending) { true } + let(:error) { nil } + + it_behaves_like 'valid_outgoing_frame' + + context 'should properly encode close frame' do + let(:frame_type) { :close } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x81\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode ping frame' do + let(:frame_type) { :ping } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x82\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode pong frame' do + let(:frame_type) { :pong } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x83\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode text frame' do + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x84\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode 256 bytes binary frame' do + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 256 } + let(:encoded_text) { "\x85\x7E\x01\x00" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode 64KiB binary frame' do + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 65_536 } + let(:encoded_text) { "\x85\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should return error for unknown frame type' do + let(:frame_type) { :unknown } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { nil } + let(:error) { :unknown_frame_type } + let(:require_sending) { false } + + it_behaves_like 'valid_outgoing_frame' + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_05_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_05_spec.rb new file mode 100644 index 0000000..cd26dd5 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_05_spec.rb @@ -0,0 +1,81 @@ +# encoding: binary +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Outgoing frame draft 05' do + subject { frame } + + let(:version) { 5 } + let(:frame) { WebSocket::Frame::Outgoing.new(version: version, data: decoded_text, type: frame_type) } + let(:decoded_text) { '' } + let(:encoded_text) { "\x84\x00" } + let(:frame_type) { :text } + let(:require_sending) { true } + let(:error) { nil } + + it_behaves_like 'valid_outgoing_frame' + + context 'should properly encode close frame' do + let(:frame_type) { :close } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x81\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode ping frame' do + let(:frame_type) { :ping } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x82\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode pong frame' do + let(:frame_type) { :pong } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x83\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode text frame' do + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x84\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode 256 bytes binary frame' do + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 256 } + let(:encoded_text) { "\x85\x7E\x01\x00" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode 64KiB binary frame' do + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 65_536 } + let(:encoded_text) { "\x85\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should return error for unknown frame type' do + let(:frame_type) { :unknown } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { nil } + let(:error) { :unknown_frame_type } + let(:require_sending) { false } + + it_behaves_like 'valid_outgoing_frame' + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_07_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_07_spec.rb new file mode 100644 index 0000000..6441825 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_07_spec.rb @@ -0,0 +1,92 @@ +# encoding: binary +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Outgoing frame draft 07' do + subject { frame } + + let(:version) { 7 } + let(:frame) { WebSocket::Frame::Outgoing.new(version: version, data: decoded_text, type: frame_type, code: close_code) } + let(:decoded_text) { '' } + let(:close_code) { nil } + let(:encoded_text) { "\x81\x00" } + let(:frame_type) { :text } + let(:require_sending) { true } + let(:error) { nil } + + it_behaves_like 'valid_outgoing_frame' + + context 'should properly encode close frame without close code' do + let(:frame_type) { :close } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x88\x07\x03\xE8" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode close frame with close code' do + let(:frame_type) { :close } + let(:decoded_text) { 'Hello' } + let(:close_code) { 1001 } + let(:encoded_text) { "\x88\x07\x03\xE9" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode ping frame' do + let(:frame_type) { :ping } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x89\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode pong frame' do + let(:frame_type) { :pong } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x8a\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode text frame' do + let(:decoded_text) { 'Hello' } + let(:encoded_text) { "\x81\x05" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode 256 bytes binary frame' do + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 256 } + let(:encoded_text) { "\x82\x7E\x01\x00" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode 64KiB binary frame' do + let(:frame_type) { :binary } + let(:decoded_text) { 'a' * 65_536 } + let(:encoded_text) { "\x82\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should return error for unknown frame type' do + let(:frame_type) { :unknown } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { nil } + let(:error) { :unknown_frame_type } + let(:require_sending) { false } + + it_behaves_like 'valid_outgoing_frame' + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_75_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_75_spec.rb new file mode 100644 index 0000000..a7e5f2c --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_75_spec.rb @@ -0,0 +1,45 @@ +# encoding: binary +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Outgoing frame draft 75' do + subject { frame } + + let(:version) { 75 } + let(:frame) { WebSocket::Frame::Outgoing.new(version: version, data: decoded_text, type: frame_type) } + let(:decoded_text) { '' } + let(:encoded_text) { "\x00\xFF" } + let(:frame_type) { :text } + let(:require_sending) { true } + let(:error) { nil } + + it_behaves_like 'valid_outgoing_frame' + + context 'should properly encode text frame' do + let(:decoded_text) { 'abc' } + let(:encoded_text) { "\x00abc\xFF" } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should properly encode close frame' do + let(:frame_type) { :close } + let(:decoded_text) { 'abc' } + let(:encoded_text) { "\xFF\x00" } + let(:require_sending) { true } + + it_behaves_like 'valid_outgoing_frame' + end + + context 'should return error for unknown frame type' do + let(:frame_type) { :unknown } + let(:decoded_text) { 'Hello' } + let(:encoded_text) { nil } + let(:error) { :unknown_frame_type } + let(:require_sending) { false } + + it_behaves_like 'valid_outgoing_frame' + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_common_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_common_spec.rb new file mode 100644 index 0000000..f3e53de --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/frame/outgoing_common_spec.rb @@ -0,0 +1,22 @@ +# encoding: binary +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Outgoing common frame' do + subject { WebSocket::Frame::Outgoing.new } + + it 'is version 13' do + expect(subject.version).to be 13 + end + + it 'has no errors' do + expect(subject.error?).to be false + end + + it 'raises error on invalid version' do + subject = WebSocket::Frame::Incoming.new(version: 70) + expect(subject.error?).to be true + expect(subject.error).to be :unknown_protocol_version + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/client_04_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/client_04_spec.rb new file mode 100644 index 0000000..a2b2f2b --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/client_04_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Client draft 4 handshake' do + let(:handshake) { WebSocket::Handshake::Client.new({ uri: 'ws://example.com/demo', origin: 'http://example.com', version: version }.merge(@request_params || {})) } + + let(:version) { 4 } + let(:client_request) { client_handshake_04({ key: handshake.handler.send(:key), version: version }.merge(@request_params || {})) } + let(:server_response) { server_handshake_04({ accept: handshake.handler.send(:accept) }.merge(@request_params || {})) } + + it_behaves_like 'all client drafts' + + it 'disallows client with invalid challenge' do + @request_params = { accept: 'invalid' } + handshake << server_response + + expect(handshake).to be_finished + expect(handshake).not_to be_valid + expect(handshake.error).to be(:invalid_handshake_authentication) + end + + context 'protocol header specified' do + let(:handshake) { WebSocket::Handshake::Client.new(uri: 'ws://example.com/demo', origin: 'http://example.com', version: version, protocols: protocols) } + + context 'single protocol requested' do + let(:protocols) { %w[binary] } + + it 'returns a valid handshake' do + @request_params = { headers: { 'Sec-WebSocket-Protocol' => 'binary' } } + handshake << server_response + + expect(handshake).to be_finished + expect(handshake).to be_valid + end + end + + context 'multiple protocols requested' do + let(:protocols) { %w[binary xmpp] } + + it 'returns with a valid handshake' do + @request_params = { headers: { 'Sec-WebSocket-Protocol' => 'xmpp' } } + handshake << server_response + + expect(handshake).to be_finished + expect(handshake).to be_valid + end + end + + context 'unsupported protocol requested' do + let(:protocols) { %w[binary xmpp] } + + it 'fails with an unsupported protocol error' do + @request_params = { headers: { 'Sec-WebSocket-Protocol' => 'generic' } } + handshake << server_response + + expect(handshake).to be_finished + expect(handshake).not_to be_valid + expect(handshake.error).to be(:unsupported_protocol) + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/client_11_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/client_11_spec.rb new file mode 100644 index 0000000..c80c536 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/client_11_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Client draft 11 handshake' do + let(:handshake) { WebSocket::Handshake::Client.new({ uri: 'ws://example.com/demo', origin: 'http://example.com', version: version }.merge(@request_params || {})) } + + let(:version) { 11 } + let(:client_request) { client_handshake_11({ key: handshake.handler.send(:key), version: version }.merge(@request_params || {})) } + let(:server_response) { server_handshake_11({ accept: handshake.handler.send(:accept) }.merge(@request_params || {})) } + + it_behaves_like 'all client drafts' + + it 'disallows client with invalid challenge' do + @request_params = { accept: 'invalid' } + handshake << server_response + + expect(handshake).to be_finished + expect(handshake).not_to be_valid + expect(handshake.error).to be(:invalid_handshake_authentication) + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/client_75_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/client_75_spec.rb new file mode 100644 index 0000000..69e25ab --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/client_75_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Client draft 75 handshake' do + let(:handshake) { WebSocket::Handshake::Client.new({ uri: 'ws://example.com/demo', origin: 'http://example.com', version: version }.merge(@request_params || {})) } + + let(:version) { 75 } + let(:client_request) { client_handshake_75(@request_params || {}) } + let(:server_response) { server_handshake_75(@request_params || {}) } + + it_behaves_like 'all client drafts' + + context 'protocol header specified' do + let(:handshake) { WebSocket::Handshake::Client.new(uri: 'ws://example.com/demo', origin: 'http://example.com', version: version, protocols: %w[binary]) } + + context 'supported' do + it 'returns a valid handshake' do + @request_params = { headers: { 'WebSocket-Protocol' => 'binary' } } + handshake << server_response + + expect(handshake).to be_finished + expect(handshake).to be_valid + end + end + + context 'unsupported' do + it 'fails with an unsupported protocol error' do + @request_params = { headers: { 'WebSocket-Protocol' => 'xmpp' } } + handshake << server_response + + expect(handshake).to be_finished + expect(handshake).not_to be_valid + expect(handshake.error).to be(:unsupported_protocol) + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/client_76_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/client_76_spec.rb new file mode 100644 index 0000000..edc6847 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/client_76_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Client draft 76 handshake' do + let(:handshake) { WebSocket::Handshake::Client.new({ uri: 'ws://example.com/demo', origin: 'http://example.com', version: version }.merge(@request_params || {})) } + + let(:version) { 76 } + let(:client_request) { client_handshake_76({ key1: handshake.handler.send(:key1), key2: handshake.handler.send(:key2), key3: handshake.handler.send(:key3) }.merge(@request_params || {})) } + let(:server_response) { server_handshake_76({ challenge: handshake.handler.send(:challenge) }.merge(@request_params || {})) } + + it_behaves_like 'all client drafts' + + it 'disallows client with invalid challenge' do + @request_params = { challenge: 'invalid' } + handshake << server_response + + expect(handshake).to be_finished + expect(handshake).not_to be_valid + expect(handshake.error).to be(:invalid_handshake_authentication) + end + + context 'protocol header specified' do + let(:handshake) { WebSocket::Handshake::Client.new(uri: 'ws://example.com/demo', origin: 'http://example.com', version: version, protocols: %w[binary]) } + + context 'supported' do + it 'returns a valid handshake' do + @request_params = { headers: { 'Sec-WebSocket-Protocol' => 'binary' } } + handshake << server_response + + expect(handshake).to be_finished + expect(handshake).to be_valid + end + end + + context 'unsupported' do + it 'fails with an unsupported protocol error' do + @request_params = { headers: { 'Sec-WebSocket-Protocol' => 'xmpp' } } + handshake << server_response + + expect(handshake).to be_finished + expect(handshake).not_to be_valid + expect(handshake.error).to be(:unsupported_protocol) + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/server_04_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/server_04_spec.rb new file mode 100644 index 0000000..851e900 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/server_04_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Server draft 04 handshake' do + let(:handshake) { WebSocket::Handshake::Server.new } + let(:version) { 4 } + let(:client_request) { client_handshake_04(@request_params || {}) } + let(:server_response) { server_handshake_04(@request_params || {}) } + + it_behaves_like 'all server drafts' + + it 'disallows request without Sec-WebSocket-Key' do + handshake << client_request.gsub(/^Sec-WebSocket-Key:.*\n/, '') + + expect(handshake).to be_finished + expect(handshake).not_to be_valid + expect(handshake.error).to be(:invalid_handshake_authentication) + end + + context 'protocol header specified' do + let(:handshake) { WebSocket::Handshake::Server.new(protocols: %w[binary xmpp]) } + + context 'single protocol requested' do + it 'returns with the same protocol' do + @request_params = { headers: { 'Sec-WebSocket-Protocol' => 'binary' } } + handshake << client_request + + expect(handshake.to_s).to match('Sec-WebSocket-Protocol: binary') + end + end + + context 'multiple protocols requested' do + it 'returns with the first supported protocol' do + @request_params = { headers: { 'Sec-WebSocket-Protocol' => 'xmpp, binary' } } + handshake << client_request + + expect(handshake.to_s).to match('Sec-WebSocket-Protocol: xmpp') + end + end + + context 'unsupported protocol requested' do + it 'reutrns with an empty protocol header' do + @request_params = { headers: { 'Sec-WebSocket-Protocol' => 'generic' } } + handshake << client_request + + expect(handshake.to_s).to match("Sec-WebSocket-Protocol: \r\n") + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/server_75_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/server_75_spec.rb new file mode 100644 index 0000000..dcadf35 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/server_75_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Server draft 75 handshake' do + let(:handshake) { WebSocket::Handshake::Server.new } + + let(:version) { 75 } + let(:client_request) { client_handshake_75(@request_params || {}) } + let(:server_response) { server_handshake_75(@request_params || {}) } + + it_behaves_like 'all server drafts' + + context 'protocol header specified' do + let(:handshake) { WebSocket::Handshake::Server.new(protocols: %w[binary]) } + + context 'supported' do + it 'returns with the same protocol' do + @request_params = { headers: { 'WebSocket-Protocol' => 'binary' } } + handshake << client_request + + expect(handshake.to_s).to match('WebSocket-Protocol: binary') + end + end + + context 'unsupported' do + it 'returns with an empty protocol header' do + @request_params = { headers: { 'WebSocket-Protocol' => 'xmpp' } } + handshake << client_request + + expect(handshake.to_s).to match("WebSocket-Protocol: \r\n") + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/server_76_spec.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/server_76_spec.rb new file mode 100644 index 0000000..b87d587 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/handshake/server_76_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Server draft 76 handshake' do + let(:handshake) { WebSocket::Handshake::Server.new } + let(:version) { 76 } + let(:client_request) { client_handshake_76(@request_params || {}) } + let(:server_response) { server_handshake_76(@request_params || {}) } + + it_behaves_like 'all server drafts' + + it 'disallows request without spaces in key 1' do + @request_params = { key1: '4@146546xW%0l15' } + handshake << client_request + + expect(handshake).to be_finished + expect(handshake).not_to be_valid + expect(handshake.error).to be(:invalid_handshake_authentication) + end + + it 'disallows request without spaces in key 2' do + @request_params = { key2: '129985Y31.P00' } + handshake << client_request + + expect(handshake).to be_finished + expect(handshake).not_to be_valid + expect(handshake.error).to be(:invalid_handshake_authentication) + end + + it 'disallows request with invalid number of spaces or numbers in key 1' do + @request_params = { key1: '4 @1 46546xW%0l 1 5' } + handshake << client_request + + expect(handshake).to be_finished + expect(handshake).not_to be_valid + expect(handshake.error).to be(:invalid_handshake_authentication) + end + + it 'disallows request with invalid number of spaces or numbers in key 2' do + @request_params = { key2: '12998 5 Y3 1 .P00' } + handshake << client_request + + expect(handshake).to be_finished + expect(handshake).not_to be_valid + expect(handshake.error).to be(:invalid_handshake_authentication) + end + + context 'protocol header specified' do + let(:handshake) { WebSocket::Handshake::Server.new(protocols: %w[binary]) } + + context 'supported' do + it 'returns with the same protocol' do + @request_params = { headers: { 'Sec-WebSocket-Protocol' => 'binary' } } + handshake << client_request + + expect(handshake.to_s).to match('Sec-WebSocket-Protocol: binary') + end + end + + context 'unsupported' do + it 'returns with an empty protocol header' do + @request_params = { headers: { 'Sec-WebSocket-Protocol' => 'xmpp' } } + handshake << client_request + + expect(handshake.to_s).to match("Sec-WebSocket-Protocol: \r\n") + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/spec_helper.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/spec_helper.rb new file mode 100644 index 0000000..1fb8ecb --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/spec_helper.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'rspec' + +require 'websocket' +Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } + +RSpec.configure do |config| + config.disable_monkey_patching! + + config.before(:suite) do + WebSocket.max_frame_size = 100 * 1024 # 100kb + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/all_client_drafts.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/all_client_drafts.rb new file mode 100644 index 0000000..f032e4b --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/all_client_drafts.rb @@ -0,0 +1,114 @@ +# frozen_string_literal: true + +RSpec.shared_examples_for 'all client drafts' do + def validate_request + expect(handshake.to_s).to eql(client_request) + + handshake << server_response + + expect(handshake.error).to be_nil + expect(handshake).to be_finished + expect(handshake).to be_valid + end + + it 'is valid' do + handshake << server_response + + expect(handshake.error).to be_nil + expect(handshake).to be_finished + expect(handshake).to be_valid + end + + it 'returns valid version' do + expect(handshake.version).to eql(version) + end + + it 'returns valid host' do + @request_params = { host: 'www.test.cc' } + expect(handshake.host).to eql('www.test.cc') + end + + it 'returns valid path' do + @request_params = { path: '/custom' } + expect(handshake.path).to eql('/custom') + end + + it 'returns valid query' do + @request_params = { query: 'aaa=bbb' } + expect(handshake.query).to eql('aaa=bbb') + end + + it 'returns default port' do + expect(handshake.port).to be(80) + end + + it 'returns valid port' do + @request_params = { port: 123 } + expect(handshake.port).to be(123) + end + + it 'returns valid headers' do + @request_params = { headers: { 'aaa' => 'bbb' } } + expect(handshake.headers).to eql('aaa' => 'bbb') + end + + it 'parses uri' do + @request_params = { uri: 'ws://test.example.org:301/test_path?query=true' } + expect(handshake.host).to eql('test.example.org') + expect(handshake.port).to be(301) + expect(handshake.path).to eql('/test_path') + expect(handshake.query).to eql('query=true') + end + + it 'parses url' do + @request_params = { url: 'ws://test.example.org:301/test_path?query=true' } + expect(handshake.host).to eql('test.example.org') + expect(handshake.port).to be(301) + expect(handshake.path).to eql('/test_path') + expect(handshake.query).to eql('query=true') + end + + it 'resolves correct path with root server provided' do + @request_params = { url: 'ws://test.example.org' } + expect(handshake.path).to eql('/') + end + + it 'returns valid response' do + validate_request + end + + it 'allows custom path' do + @request_params = { path: '/custom' } + validate_request + end + + it 'allows query in path' do + @request_params = { query: 'test=true' } + validate_request + end + + it 'allows custom port' do + @request_params = { port: 123 } + validate_request + end + + it 'allows custom headers' do + @request_params = { headers: { 'aaa' => 'bbb' } } + validate_request + end + + it 'recognizes unfinished requests' do + handshake << server_response[0..-20] + + expect(handshake).not_to be_finished + expect(handshake).not_to be_valid + end + + it 'disallows requests with invalid request method' do + handshake << server_response.gsub('101', '404') + + expect(handshake).to be_finished + expect(handshake).not_to be_valid + expect(handshake.error).to be(:invalid_status_code) + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/all_server_drafts.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/all_server_drafts.rb new file mode 100644 index 0000000..dea93b9 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/all_server_drafts.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +require 'webrick' + +RSpec.shared_examples_for 'all server drafts' do + def validate_request + handshake << client_request + + expect(handshake.error).to be_nil + expect(handshake).to be_finished + expect(handshake).to be_valid + expect(handshake.to_s).to eql(server_response) + end + + it 'is valid' do + handshake << client_request + + expect(handshake.error).to be_nil + expect(handshake).to be_finished + expect(handshake).to be_valid + end + + it 'returns valid version' do + handshake << client_request + + expect(handshake.version).to eql(version) + end + + it 'returns valid host' do + @request_params = { host: 'www.test.cc' } + handshake << client_request + + expect(handshake.host).to eql('www.test.cc') + end + + it 'returns valid path' do + @request_params = { path: '/custom' } + handshake << client_request + + expect(handshake.path).to eql('/custom') + end + + it 'returns valid query' do + @request_params = { path: '/custom?aaa=bbb' } + handshake << client_request + + expect(handshake.query).to eql('aaa=bbb') + end + + it 'returns default port' do + handshake << client_request + + expect(handshake.port).to be(80) + end + + it 'returns valid port' do + @request_params = { port: 123 } + handshake << client_request + + expect(handshake.port).to be(123) + end + + it 'returns valid response' do + validate_request + end + + it 'allows custom path' do + @request_params = { path: '/custom' } + validate_request + end + + it 'allows query in path' do + @request_params = { path: '/custom?test=true' } + validate_request + end + + it 'allows custom port' do + @request_params = { port: 123 } + validate_request + end + + it 'recognizes unfinished requests' do + handshake << client_request[0..-10] + + expect(handshake).not_to be_finished + expect(handshake).not_to be_valid + end + + it 'disallows requests with invalid request method' do + handshake << client_request.gsub('GET', 'POST') + + expect(handshake).to be_finished + expect(handshake).not_to be_valid + expect(handshake.error).to be(:get_request_required) + end + + it 'parses a rack request' do + request = WEBrick::HTTPRequest.new(ServerSoftware: 'rspec') + expect(request.parse(StringIO.new(client_request))).to be true + rest = client_request.slice((request.to_s.length..-1)) + + handshake.from_rack(request.meta_vars.merge( + 'rack.input' => StringIO.new(rest), + :random_key => :random_value + )) + validate_request + end + + it 'parses a hash request' do + request = WEBrick::HTTPRequest.new(ServerSoftware: 'rspec') + expect(request.parse(StringIO.new(client_request))).to be true + body = client_request.slice((request.to_s.length..-1)) + + path = request.path + query = request.query_string + headers = request.header.each_with_object({}) do |header, hash| + hash[header[0]] = header[1].first if header[0] && header[1] + end + + handshake.from_hash(headers: headers, + path: path, + query: query, + body: body) + + validate_request + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/frames_base.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/frames_base.rb new file mode 100644 index 0000000..7ce696c --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/frames_base.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module WebSocket + module Frame + class Base + def incoming_masking? + @handler.masking? + end + + def outgoing_masking? + false + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/handshake_requests.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/handshake_requests.rb new file mode 100644 index 0000000..da86c5b --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/handshake_requests.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +def client_handshake_75(args = {}) + <<-REQUEST +GET #{args[:path] || '/demo'}#{"?#{args[:query]}" if args[:query]} HTTP/1.1\r +Upgrade: WebSocket\r +Connection: Upgrade\r +Host: #{args[:host] || 'example.com'}#{":#{args[:port]}" if args[:port]}\r +Origin: http://example.com\r +#{(args[:headers] || {}).map { |key, value| "#{key}: #{value}\r\n" }.join('')}\r + REQUEST +end + +def server_handshake_75(args = {}) + <<-REQUEST +HTTP/1.1 101 Web Socket Protocol Handshake\r +Upgrade: WebSocket\r +Connection: Upgrade\r +#{(args[:headers] || {}).map { |key, value| "#{key}: #{value}\r\n" }.join('')}WebSocket-Origin: http://example.com\r +WebSocket-Location: ws#{args[:secure] ? 's' : ''}://#{args[:host] || 'example.com'}#{":#{args[:port]}" if args[:port]}#{args[:path] || '/demo'}\r +\r + REQUEST +end + +def client_handshake_76(args = {}) + request = <<-REQUEST +GET #{args[:path] || '/demo'}#{"?#{args[:query]}" if args[:query]} HTTP/1.1\r +Upgrade: WebSocket\r +Connection: Upgrade\r +Host: #{args[:host] || 'example.com'}#{":#{args[:port]}" if args[:port]}\r +Origin: http://example.com\r +#{(args[:headers] || {}).map { |key, value| "#{key}: #{value}\r\n" }.join('')}Sec-WebSocket-Key1: #{args[:key1] || '4 @1 46546xW%0l 1 5'}\r +Sec-WebSocket-Key2: #{args[:key2] || '12998 5 Y3 1 .P00'}\r +\r +#{args[:key3] || '^n:ds[4U'} + REQUEST + request[0..-2] +end + +def server_handshake_76(args = {}) + request = <<-REQUEST +HTTP/1.1 101 WebSocket Protocol Handshake\r +Upgrade: WebSocket\r +Connection: Upgrade\r +#{(args[:headers] || {}).map { |key, value| "#{key}: #{value}\r\n" }.join('')}Sec-WebSocket-Origin: http://example.com\r +Sec-WebSocket-Location: ws#{args[:secure] ? 's' : ''}://#{args[:host] || 'example.com'}#{":#{args[:port]}" if args[:port]}#{args[:path] || '/demo'}\r +\r +#{args[:challenge] || "8jKS'y:G*Co,Wxa-"} + REQUEST + request[0..-2] +end + +def client_handshake_04(args = {}) + <<-REQUEST +GET #{args[:path] || '/demo'}#{"?#{args[:query]}" if args[:query]} HTTP/1.1\r +Upgrade: websocket\r +Connection: Upgrade\r +Host: #{args[:host] || 'example.com'}#{":#{args[:port]}" if args[:port]}\r +#{(args[:headers] || {}).map { |key, value| "#{key}: #{value}\r\n" }.join('')}Sec-WebSocket-Origin: http://example.com\r +Sec-WebSocket-Version: #{args[:version] || '4'}\r +Sec-WebSocket-Key: #{args[:key] || 'dGhlIHNhbXBsZSBub25jZQ=='}\r +\r + REQUEST +end + +def server_handshake_04(args = {}) + <<-REQUEST +HTTP/1.1 101 Switching Protocols\r +Upgrade: websocket\r +Connection: Upgrade\r +#{(args[:headers] || {}).map { |key, value| "#{key}: #{value}\r\n" }.join('')}Sec-WebSocket-Accept: #{args[:accept] || 's3pPLMBiTxaQ9kYGzzhZRbK+xOo='}\r +\r + REQUEST +end + +def client_handshake_11(args = {}) + <<-REQUEST +GET #{args[:path] || '/demo'}#{"?#{args[:query]}" if args[:query]} HTTP/1.1\r +Upgrade: websocket\r +Connection: Upgrade\r +Host: #{args[:host] || 'example.com'}#{":#{args[:port]}" if args[:port]}\r +#{(args[:headers] || {}).map { |key, value| "#{key}: #{value}\r\n" }.join('')}Origin: http://example.com\r +Sec-WebSocket-Version: #{args[:version] || '4'}\r +Sec-WebSocket-Key: #{args[:key] || 'dGhlIHNhbXBsZSBub25jZQ=='}\r +\r + REQUEST +end + +def server_handshake_11(args = {}) + server_handshake_04(args) +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/incoming_frames.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/incoming_frames.rb new file mode 100644 index 0000000..3f3ec8a --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/incoming_frames.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +RSpec.shared_examples_for 'valid_incoming_frame' do + let(:decoded_text_array) { Array(decoded_text) } + let(:frame_type_array) { Array(frame_type) } + + it 'is incoming frame' do + expect(subject.class).to be WebSocket::Frame::Incoming + end + + it 'is in proper verions' do + expect(subject.version).to eql version + end + + it 'does not have type set' do + expect(subject.type).to be nil + end + + it 'is not decoded' do + expect(subject.decoded?).to be false + end + + it 'contains encoded data' do + expect(subject.data).to eql(encoded_text || '') + end + + it 'returns data as to_s' do + expect(subject.to_s).to eql(encoded_text || '') + end + + it 'has specified number of returned frames' do + decoded_text_array.each_with_index do |da, index| + n = subject.next + expect(n).not_to be_nil, "Should return frame for #{da}, #{frame_type_array[index]}" + expect(n.class).to eql(WebSocket::Frame::Incoming), "Should be WebSocket::Frame::Incoming, #{n} received instead" + end + expect(subject.next).to be_nil + if error.is_a?(Class) + expect(subject.error).to eql(error.new.message) + else + expect(subject.error).to eql(error) + end + end + + it 'returns valid decoded frame for each specified decoded texts' do + decoded_text_array.each_with_index do |da, index| + f = subject.next + expect(f.decoded?).to be true + expect(f.type).to eql(frame_type_array[index]) + expect(f.code).to eql(close_code) if defined?(close_code) + expect(f.to_s).to eql(da) + end + end + + context 'with raising' do + before { WebSocket.should_raise = true } + after { WebSocket.should_raise = false } + + it 'has specified number of returned frames' do + if error + expect do + decoded_text_array.each_with_index do |da, index| + n = subject.next + expect(n).not_to be_nil, "Should return frame for #{da}, #{frame_type_array[index]}" + expect(n.class).to eql(WebSocket::Frame::Incoming), "Should be WebSocket::Frame::Incoming, #{n} received instead" + end + expect(subject.next).to be_nil + if error.is_a?(Class) + expect(subject.error).to eql(error.new.message) + else + expect(subject.error).to eql(error) + end + end.to raise_error(error) + end + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/outgoing_frames.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/outgoing_frames.rb new file mode 100644 index 0000000..f14f47f --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/outgoing_frames.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +RSpec.shared_examples_for 'valid_outgoing_frame' do + it 'is outgoing frame' do + expect(subject.class).to be WebSocket::Frame::Outgoing + end + + it 'is in proper verions' do + expect(subject.version).to eql version + end + + it 'has proper type set' do + expect(subject.type).to eql frame_type + end + + it 'contains decoded data' do + expect(subject.data).to eql(decoded_text) + end + + it 'returns encoded data as to_s' do + expect(subject.to_s).to eql(encoded_text) + end + + context 'after parsing' do + before { subject.to_s } + + it 'has valid errors set' do + expect(subject.error).to eql error + end + + it 'requires sending' do + expect(subject.require_sending?).to eql require_sending + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/overwrites.rb b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/overwrites.rb new file mode 100644 index 0000000..2bd048a --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/spec/support/overwrites.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module WebSocket + module Handshake + class Base + attr_reader :handler + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-1.2.10/websocket.gemspec b/games/FNaFB2/Ruby/gems/websocket-1.2.10/websocket.gemspec new file mode 100644 index 0000000..764c6c4 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-1.2.10/websocket.gemspec @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +$LOAD_PATH.push File.expand_path('../lib', __FILE__) +require 'websocket/version' + +Gem::Specification.new do |s| + s.name = 'websocket' + s.version = WebSocket::VERSION + s.platform = Gem::Platform::RUBY + s.authors = ['Bernard Potocki'] + s.email = ['bernard.potocki@imanel.org'] + s.homepage = 'http://github.com/imanel/websocket-ruby' + s.summary = 'Universal Ruby library to handle WebSocket protocol' + s.description = 'Universal Ruby library to handle WebSocket protocol' + s.license = 'MIT' + + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) } + s.require_paths = ['lib'] + + s.required_ruby_version = '>= 2.0' +end diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/.github/workflows/test.yml b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/.github/workflows/test.yml new file mode 100644 index 0000000..f246d12 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/.github/workflows/test.yml @@ -0,0 +1,23 @@ +on: + push: + branches: + - "*" + pull_request: + branches: + - "*" + schedule: + - cron: "0 0 * * 6" # At 00:00 on Saturday +jobs: + test: + runs-on: ubuntu-22.04 + strategy: + matrix: + ruby: ["3.2", "3.1", "3.0", "2.7", "2.6"] + name: Ruby ${{ matrix.ruby }} + steps: + - uses: actions/checkout@v3 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + - run: bundle exec rake diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/.gitignore b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/.gitignore new file mode 100644 index 0000000..3319b97 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/.gitignore @@ -0,0 +1,18 @@ +*.gem +*.rbc +.bundle +.config +.yardoc +InstalledFiles +_yardoc +coverage +doc/ +lib/bundler/man +pkg +rdoc +spec/reports +test/tmp +test/version_tmp +tmp +Gemfile.lock +.ruby-version diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/CHANGELOG.md b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/CHANGELOG.md new file mode 100644 index 0000000..3cbc961 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/CHANGELOG.md @@ -0,0 +1,88 @@ +# Changelog + +## Not yet released + +## 0.8.0 - 2023-08-08 +* Set `WebSocket.should_raise = true` https://github.com/ruby-jp/websocket-client-simple/pull/25 by @jlaffaye + +## 0.7.0 - 2023-08-04 +* Expose add accessor `Client#thread` #22 by @jlaffaye +* Rewrite changelog as a Markdown + +## 0.6.1 - 2023-03-10 +* Make `#open?` safe to use when `@handshake` is `nil` #20 by @cyberarm + +## 0.6.0 - 2022-09-22 +* Add option `cert_store` for passing cert store to SSLSocket context #12 by @DerekStride +* Set `OpenSSL::SSL::SSLSocket#sync_close` to `true` #12 by @DerekStride + +## 0.5.1 - 2022-01-01 +* Add `closed?` method to `WebSocket::Client::Simple` #8 by @fuyuton +* rescue when `OpenSSL::SSL::SSLError` raised #10 by @fuyuton + +## 0.5.0 - 2021-12-31 +* Change TLS context defaults to system's default. The previous defaults were `ssl_version=SSLv23` and `verify_mode=VERIFY_NONE`, which are insecure nowadays. #5 + * thank you for contributing @eagletmt +* Made the necessary changes to use SNI. #6 + * thank you for contributing @fuyuton + +## 0.4.0 - 2021-12-30 +* Drop support of ruby 2.5 or older versions as explicit. + +## 0.3.1 - 2021-12-30 +* The development of this repository has moved to https://github.com/ruby-jp/websocket-client-simple + +## 0.3.0 - 2016-12-30 +* `connect` method runs a given block before connecting WebSocket [#12](https://github.com/shokai/websocket-client-simple/issues/12) + * thank you for suggestion @codekitchen + +## 0.2.5 - 2016-02-18 +* bugfixed sending when broken pipe [#15](https://github.com/shokai/websocket-client-simple/pull/15) +* add `:verify_mode` option for SSL Context [#14](https://github.com/shokai/websocket-client-simple/pull/14) + * thank you for contributing @michaelvilensky + +## 0.2.4 - 2015-11-12 +* support handshake headers [#11](https://github.com/shokai/websocket-client-simple/pull/11) + * thank you for contributing @mathieugagne + +## 0.2.3 - 2015-10-26 +* kill thread at end of method [#10](https://github.com/shokai/websocket-client-simple/pull/10) + * thank you for contributing @hansy + +## 0.2.2 - 2014-11-18 +* bugfix socket reading + +## 0.2.0 - 2014-06-07 +* SSL support with `wss://` and `https://` scheme [#6](https://github.com/shokai/websocket-client-simple/pull/6) + * thank you for contributing @mallowlabs + +## 0.1.0 - 2014-05-08 +* add accessor `Client#handshake` [#5](https://github.com/shokai/websocket-client-simple/issues/5) +* bugfix socket reading + +## 0.0.9 - 2014-04-03 +* emit `error` in receive thread +* rescue only `Errno::EPIPE`, not all Errors + +## 0.0.8 - 2014-01-29 +* bugfix `Client#close` #4 + +## 0.0.7 - 2014-01-29 +* send CLOSE frame in `Client#close` [#4](https://github.com/shokai/websocket-client-simple/issues/4) +## 0.0.6 - 2014-01-17 +* add function `Client#open?` + +## 0.0.5 - 2013-03-23 +* kill read thread on close + +## 0.0.4 - 2013-03-23 +* fix sample and README + +## 0.0.3 - 2013-03-23 +* `:type => :text` option in send + +## 0.0.2 - 2013-03-22 +* remove unnecessary sleep + +## 0.0.1 - 2013-03-22 +* release diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/Gemfile b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/Gemfile new file mode 100644 index 0000000..4e2845b --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +# Specify your gem's dependencies in websocket-client-simple.gemspec +gemspec diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/LICENSE.txt b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/LICENSE.txt new file mode 100644 index 0000000..adafeda --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2013-2014 Sho Hashimoto + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/README.md b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/README.md new file mode 100644 index 0000000..b4d20c0 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/README.md @@ -0,0 +1,80 @@ +websocket-client-simple +======================= +Simple WebSocket Client for Ruby (original author: @shokai) + +- https://github.com/ruby-jp/websocket-client-simple +- https://rubygems.org/gems/websocket-client-simple + +[![.github/workflows/test.yml](https://github.com/ruby-jp/websocket-client-simple/actions/workflows/test.yml/badge.svg)](https://github.com/ruby-jp/websocket-client-simple/actions/workflows/test.yml) + +Installation +------------ + + gem install websocket-client-simple + + +Usage +----- +```ruby +require 'websocket-client-simple' + +ws = WebSocket::Client::Simple.connect 'ws://example.com:8888' + +ws.on :message do |msg| + puts msg.data +end + +ws.on :open do + ws.send 'hello!!!' +end + +ws.on :close do |e| + p e + exit 1 +end + +ws.on :error do |e| + p e +end + +loop do + ws.send STDIN.gets.strip +end +``` + +`connect` runs a given block before connecting websocket + +```ruby +WebSocket::Client::Simple.connect 'ws://example.com:8888' do |ws| + ws.on :open do + puts "connect!" + end + + ws.on :message do |msg| + puts msg.data + end +end +``` + + +Sample +------ +[websocket chat](https://github.com/ruby-jp/websocket-client-simple/tree/master/sample) + + +Test +---- + + % gem install bundler + % bundle install + % export WS_PORT=8888 + % rake test + + +Contributing +------------ +1. Fork it +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Add some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create new Pull Request diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/Rakefile b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/Rakefile new file mode 100644 index 0000000..3ea8ab5 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/Rakefile @@ -0,0 +1,8 @@ +require "bundler/gem_tasks" +require "rake/testtask" + +Rake::TestTask.new do |t| + t.pattern = "test/test_*.rb" +end + +task :default => :test diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/lib/websocket-client-simple.rb b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/lib/websocket-client-simple.rb new file mode 100644 index 0000000..35f0e41 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/lib/websocket-client-simple.rb @@ -0,0 +1,15 @@ +require 'event_emitter' +require 'websocket' +require 'socket' +require 'openssl' +require 'uri' + +require 'websocket-client-simple/version' +require 'websocket-client-simple/client' + +module WebSocket + module Client + module Simple + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/lib/websocket-client-simple/client.rb b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/lib/websocket-client-simple/client.rb new file mode 100644 index 0000000..fdea448 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/lib/websocket-client-simple/client.rb @@ -0,0 +1,112 @@ +module WebSocket + module Client + module Simple + + def self.connect(url, options={}) + client = ::WebSocket::Client::Simple::Client.new + yield client if block_given? + client.connect url, options + return client + end + + class Client + include EventEmitter + attr_reader :url, :handshake, :thread + + def connect(url, options={}) + return if @socket + @url = url + uri = URI.parse url + @socket = TCPSocket.new(uri.host, + uri.port || (uri.scheme == 'wss' ? 443 : 80)) + if ['https', 'wss'].include? uri.scheme + ctx = OpenSSL::SSL::SSLContext.new + ctx.ssl_version = options[:ssl_version] if options[:ssl_version] + ctx.verify_mode = options[:verify_mode] if options[:verify_mode] + cert_store = options[:cert_store] || OpenSSL::X509::Store.new + cert_store.set_default_paths + ctx.cert_store = cert_store + @socket = ::OpenSSL::SSL::SSLSocket.new(@socket, ctx) + @socket.sync_close = true + @socket.hostname = uri.host + @socket.connect + end + ::WebSocket.should_raise = true + @handshake = ::WebSocket::Handshake::Client.new :url => url, :headers => options[:headers] + @handshaked = false + @pipe_broken = false + frame = ::WebSocket::Frame::Incoming::Client.new + @closed = false + once :__close do |err| + close + emit :close, err + end + + @thread = Thread.new do + while !@closed do + begin + unless recv_data = @socket.getc + sleep 1 + next + end + unless @handshaked + @handshake << recv_data + if @handshake.finished? + @handshaked = true + emit :open + end + else + frame << recv_data + while msg = frame.next + emit :message, msg + end + end + rescue => e + emit :error, e + end + end + end + + @socket.write @handshake.to_s + end + + def send(data, opt={:type => :text}) + return if !@handshaked or @closed + type = opt[:type] + frame = ::WebSocket::Frame::Outgoing::Client.new(:data => data, :type => type, :version => @handshake.version) + begin + @socket.write frame.to_s + rescue Errno::EPIPE => e + @pipe_broken = true + emit :__close, e + rescue OpenSSL::SSL::SSLError => e + @pipe_broken = true + emit :__close, e + end + end + + def close + return if @closed + if !@pipe_broken + send nil, :type => :close + end + @closed = true + @socket.close if @socket + @socket = nil + emit :__close + Thread.kill @thread if @thread + end + + def open? + @handshake&.finished? and !@closed + end + + def closed? + @closed + end + + end + + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/lib/websocket-client-simple/version.rb b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/lib/websocket-client-simple/version.rb new file mode 100644 index 0000000..a6c1882 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/lib/websocket-client-simple/version.rb @@ -0,0 +1,7 @@ +module WebSocket + module Client + module Simple + VERSION = "0.8.0" + end + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/sample/client.rb b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/sample/client.rb new file mode 100644 index 0000000..8b3908c --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/sample/client.rb @@ -0,0 +1,30 @@ +#!/usr/bin/env ruby +$:.unshift File.expand_path '../lib', File.dirname(__FILE__) +require 'websocket-client-simple' + +puts "websocket-client-simple v#{WebSocket::Client::Simple::VERSION}" + +url = ARGV.shift || 'ws://localhost:8080' + +ws = WebSocket::Client::Simple.connect url + +ws.on :message do |msg| + puts ">> #{msg.data}" +end + +ws.on :open do + puts "-- websocket open (#{ws.url})" +end + +ws.on :close do |e| + puts "-- websocket close (#{e.inspect})" + exit 1 +end + +ws.on :error do |e| + puts "-- error (#{e.inspect})" +end + +loop do + ws.send STDIN.gets.strip +end diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/sample/echo_server.rb b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/sample/echo_server.rb new file mode 100644 index 0000000..fb49502 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/sample/echo_server.rb @@ -0,0 +1,34 @@ +#!/usr/bin/env ruby +require 'eventmachine' +require 'websocket-eventmachine-server' + +PORT = (ARGV.shift || 8080).to_i + +EM::run do + @channel = EM::Channel.new + + puts "start websocket server - port:#{PORT}" + + WebSocket::EventMachine::Server.start(:host => "0.0.0.0", :port => PORT) do |ws| + ws.onopen do + sid = @channel.subscribe do |mes| + ws.send mes + end + puts "<#{sid}> connect" + + @channel.push "hello new client <#{sid}>" + + ws.onmessage do |msg| + puts "<#{sid}> #{msg}" + @channel.push "<#{sid}> #{msg}" + end + + ws.onclose do + puts "<#{sid}> disconnected" + @channel.unsubscribe sid + @channel.push "<#{sid}> disconnected" + end + end + end + +end diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/sample/webbrowser/index.html b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/sample/webbrowser/index.html new file mode 100644 index 0000000..f5f1d84 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/sample/webbrowser/index.html @@ -0,0 +1,22 @@ + + + + + websocket chat + + + + +

websocket chat

+
+ + + +
+
    + + + diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/sample/webbrowser/main.js b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/sample/webbrowser/main.js new file mode 100644 index 0000000..3f1223c --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/sample/webbrowser/main.js @@ -0,0 +1,38 @@ +var ws = new WebSocket("ws://localhost:8080"); + +ws.onmessage = function(e){ + print(e.data); +}; + +ws.onopen = function(e){ + log("websocket open"); + console.log(e); +}; + +ws.onclose = function(e){ + log("websocket close"); + console.log(e); +}; + +$(function(){ + $("#btn_post").click(post); + $("#message").keydown(function(e){ + if(e.keyCode == 13) post(); + }); +}); + +var post = function(){ + var name = $("#name").val(); + var mes = $("#message").val(); + ws.send(name+" : "+mes); + $("input#message").val(""); +}; + +var log = function(msg){ + console.log(msg); + $("#chat").prepend($("
  • ").text("[log] "+msg)); +}; + +var print = function(msg){ + $("#chat").prepend($("
  • ").text(msg)); +}; diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/test/echo_server.rb b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/test/echo_server.rb new file mode 100644 index 0000000..b2d11a8 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/test/echo_server.rb @@ -0,0 +1,26 @@ +module EchoServer + def self.start + WebSocket::EventMachine::Server.start(:host => "0.0.0.0", :port => self.port) do |ws| + @channel = EM::Channel.new + ws.onopen do + sid = @channel.subscribe do |mes| + ws.send mes # echo to client + end + ws.onmessage do |msg| + @channel.push msg + end + ws.onclose do + @channel.unsubscribe sid + end + end + end + end + + def self.port + (ENV['WS_PORT'] || 18080).to_i + end + + def self.url + "ws://localhost:#{self.port}" + end +end diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/test/test_connect_block.rb b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/test/test_connect_block.rb new file mode 100644 index 0000000..8b94cd4 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/test/test_connect_block.rb @@ -0,0 +1,33 @@ +require File.expand_path 'test_helper', File.dirname(__FILE__) + +class TestWebSocketClientSimple < Minitest::Test + + def test_onopen + + EM::run{ + + EchoServer.start + + res = nil + + EM::add_timer 1 do + WebSocket::Client::Simple.connect EchoServer.url do |client| + client.on :open do + client.send "hello world" + end + + client.on :message do |msg| + res = msg.to_s + end + end + end + + EM::add_timer 2 do + assert_equal res, "hello world" + EM::stop_event_loop + end + } + + end + +end diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/test/test_helper.rb b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/test/test_helper.rb new file mode 100644 index 0000000..28ee921 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/test/test_helper.rb @@ -0,0 +1,9 @@ +require 'rubygems' +require 'bundler' +require 'minitest/autorun' +require 'websocket-client-simple' +require 'eventmachine' +require 'websocket-eventmachine-server' +require_relative 'echo_server' + +$:.unshift File.expand_path '../lib', File.dirname(__FILE__) diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/test/test_websocket_client_simple.rb b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/test/test_websocket_client_simple.rb new file mode 100644 index 0000000..d6e7914 --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/test/test_websocket_client_simple.rb @@ -0,0 +1,62 @@ +require_relative 'test_helper' + +class TestWebSocketClientSimple < Minitest::Test + + def test_echo + msgs = ['foo','bar','baz'] + res1 = [] + res2 = [] + + EM::run{ + EchoServer.start + + ## client1 --> server --> client2 + EM::add_timer 1 do + client1 = WebSocket::Client::Simple.connect EchoServer.url + client2 = WebSocket::Client::Simple.connect EchoServer.url + assert_equal client1.open?, false + assert_equal client2.open?, false + + client1.on :message do |msg| + res1.push msg + end + + client2.on :message do |msg| + res2.push msg + end + + client1.on :open do + msgs.each do |m| + client1.send m + end + end + + client1.on :close do + EM::stop_event_loop + end + + client2.on :close do + EM::stop_event_loop + end + + EM::add_timer 3 do + assert_equal client1.open?, true + assert_equal client2.open?, true + client1.close + client2.close + EM::stop_event_loop + end + end + } + + assert_equal msgs.size, res1.size + assert_equal msgs.size, res2.size + + msgs.each_with_index do |msg,i| + assert_equal msg, res1[i].to_s + assert_equal msg, res2[i].to_s + end + + end + +end diff --git a/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/websocket-client-simple.gemspec b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/websocket-client-simple.gemspec new file mode 100644 index 0000000..7b0a7ba --- /dev/null +++ b/games/FNaFB2/Ruby/gems/websocket-client-simple-0.8.0/websocket-client-simple.gemspec @@ -0,0 +1,37 @@ +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'websocket-client-simple/version' + +Gem::Specification.new do |spec| + spec.name = "websocket-client-simple" + spec.version = WebSocket::Client::Simple::VERSION + spec.authors = ["Sho Hashimoto", "Yusuke Nakamura"] + spec.email = ["hashimoto@shokai.org", "yusuke1994525@gmail.com"] + spec.description = %q{Simple WebSocket Client for Ruby} + spec.summary = spec.description + spec.homepage = "https://github.com/ruby-jp/websocket-client-simple" + spec.license = "MIT" + spec.required_ruby_version = '>= 2.6.9' + + if spec.respond_to?(:metadata) + spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["source_code_uri"] = spec.homepage + spec.metadata["changelog_uri"] = "https://github.com/ruby-jp/websocket-client-simple/blob/master/CHANGELOG.md" + end + + spec.post_install_message = "The development of this gem has moved to #{spec.homepage}." + + spec.files = `git ls-files`.split($/).reject{|f| f == "Gemfile.lock" } + spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } + spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) + spec.require_paths = ["lib"] + + spec.add_development_dependency "bundler" + spec.add_development_dependency "rake" + spec.add_development_dependency "minitest" + spec.add_development_dependency "websocket-eventmachine-server" + spec.add_development_dependency "eventmachine" + + spec.add_dependency "websocket" + spec.add_dependency "event_emitter" +end diff --git a/games/FNaFB2/Ruby/specifications/event_emitter-0.2.6.gemspec b/games/FNaFB2/Ruby/specifications/event_emitter-0.2.6.gemspec new file mode 100644 index 0000000..77b2108 --- /dev/null +++ b/games/FNaFB2/Ruby/specifications/event_emitter-0.2.6.gemspec @@ -0,0 +1,33 @@ +# -*- encoding: utf-8 -*- +# stub: event_emitter 0.2.6 ruby lib + +Gem::Specification.new do |s| + s.name = "event_emitter".freeze + s.version = "0.2.6" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib".freeze] + s.authors = ["Sho Hashimoto".freeze] + s.date = "2017-07-25" + s.description = "Ruby port of EventEmitter from Node.js".freeze + s.email = ["hashimoto@shokai.org".freeze] + s.homepage = "http://shokai.github.com/event_emitter".freeze + s.rubygems_version = "3.3.26".freeze + s.summary = "Ruby port of EventEmitter from Node.js".freeze + + s.installed_by_version = "3.3.26" if s.respond_to? :installed_by_version + + if s.respond_to? :specification_version then + s.specification_version = 4 + end + + if s.respond_to? :add_runtime_dependency then + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, ["~> 1.15"]) + else + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, ["~> 1.15"]) + end +end diff --git a/games/FNaFB2/Ruby/specifications/websocket-1.2.10.gemspec b/games/FNaFB2/Ruby/specifications/websocket-1.2.10.gemspec new file mode 100644 index 0000000..877fd73 --- /dev/null +++ b/games/FNaFB2/Ruby/specifications/websocket-1.2.10.gemspec @@ -0,0 +1,21 @@ +# -*- encoding: utf-8 -*- +# stub: websocket 1.2.10 ruby lib + +Gem::Specification.new do |s| + s.name = "websocket".freeze + s.version = "1.2.10" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib".freeze] + s.authors = ["Bernard Potocki".freeze] + s.date = "2023-09-19" + s.description = "Universal Ruby library to handle WebSocket protocol".freeze + s.email = ["bernard.potocki@imanel.org".freeze] + s.homepage = "http://github.com/imanel/websocket-ruby".freeze + s.licenses = ["MIT".freeze] + s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze) + s.rubygems_version = "3.3.26".freeze + s.summary = "Universal Ruby library to handle WebSocket protocol".freeze + + s.installed_by_version = "3.3.26" if s.respond_to? :installed_by_version +end diff --git a/games/FNaFB2/Ruby/specifications/websocket-client-simple-0.8.0.gemspec b/games/FNaFB2/Ruby/specifications/websocket-client-simple-0.8.0.gemspec new file mode 100644 index 0000000..4e0d429 --- /dev/null +++ b/games/FNaFB2/Ruby/specifications/websocket-client-simple-0.8.0.gemspec @@ -0,0 +1,45 @@ +# -*- encoding: utf-8 -*- +# stub: websocket-client-simple 0.8.0 ruby lib + +Gem::Specification.new do |s| + s.name = "websocket-client-simple".freeze + s.version = "0.8.0" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.metadata = { "changelog_uri" => "https://github.com/ruby-jp/websocket-client-simple/blob/master/CHANGELOG.md", "homepage_uri" => "https://github.com/ruby-jp/websocket-client-simple", "source_code_uri" => "https://github.com/ruby-jp/websocket-client-simple" } if s.respond_to? :metadata= + s.require_paths = ["lib".freeze] + s.authors = ["Sho Hashimoto".freeze, "Yusuke Nakamura".freeze] + s.date = "2023-08-09" + s.description = "Simple WebSocket Client for Ruby".freeze + s.email = ["hashimoto@shokai.org".freeze, "yusuke1994525@gmail.com".freeze] + s.homepage = "https://github.com/ruby-jp/websocket-client-simple".freeze + s.licenses = ["MIT".freeze] + s.post_install_message = "The development of this gem has moved to https://github.com/ruby-jp/websocket-client-simple.".freeze + s.required_ruby_version = Gem::Requirement.new(">= 2.6.9".freeze) + s.rubygems_version = "3.3.26".freeze + s.summary = "Simple WebSocket Client for Ruby".freeze + + s.installed_by_version = "3.3.26" if s.respond_to? :installed_by_version + + if s.respond_to? :specification_version then + s.specification_version = 4 + end + + if s.respond_to? :add_runtime_dependency then + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_runtime_dependency(%q.freeze, [">= 0"]) + s.add_runtime_dependency(%q.freeze, [">= 0"]) + else + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + end +end diff --git a/games/FNaFB2/Ruby/stdlib/English.rb b/games/FNaFB2/Ruby/stdlib/English.rb new file mode 100644 index 0000000..ec90ff1 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/English.rb @@ -0,0 +1,182 @@ +# frozen_string_literal: true +# Include the English library file in a Ruby script, and you can +# reference the global variables such as $_ using less +# cryptic names, listed below. +# +# Without 'English': +# +# $\ = ' -- ' +# "waterbuffalo" =~ /buff/ +# print $', $$, "\n" +# +# With English: +# +# require "English" +# +# $OUTPUT_FIELD_SEPARATOR = ' -- ' +# "waterbuffalo" =~ /buff/ +# print $POSTMATCH, $PID, "\n" +# +# Below is a full list of descriptive aliases and their associated global +# variable: +# +# $ERROR_INFO:: $! +# $ERROR_POSITION:: $@ +# $FS:: $; +# $FIELD_SEPARATOR:: $; +# $OFS:: $, +# $OUTPUT_FIELD_SEPARATOR:: $, +# $RS:: $/ +# $INPUT_RECORD_SEPARATOR:: $/ +# $ORS:: $\ +# $OUTPUT_RECORD_SEPARATOR:: $\ +# $INPUT_LINE_NUMBER:: $. +# $NR:: $. +# $LAST_READ_LINE:: $_ +# $DEFAULT_OUTPUT:: $> +# $DEFAULT_INPUT:: $< +# $PID:: $$ +# $PROCESS_ID:: $$ +# $CHILD_STATUS:: $? +# $LAST_MATCH_INFO:: $~ +# $IGNORECASE:: $= +# $ARGV:: $* +# $MATCH:: $& +# $PREMATCH:: $` +# $POSTMATCH:: $' +# $LAST_PAREN_MATCH:: $+ +# +module English end if false + +# The exception object passed to +raise+. +alias $ERROR_INFO $! + +# The stack backtrace generated by the last +# exception. See Kernel#caller for details. Thread local. +alias $ERROR_POSITION $@ + +# The default separator pattern used by String#split. May be set from +# the command line using the -F flag. +alias $FS $; + +# The default separator pattern used by String#split. May be set from +# the command line using the -F flag. +alias $FIELD_SEPARATOR $; + +# The separator string output between the parameters to methods such +# as Kernel#print and Array#join. Defaults to +nil+, which adds no +# text. +alias $OFS $, + +# The separator string output between the parameters to methods such +# as Kernel#print and Array#join. Defaults to +nil+, which adds no +# text. +alias $OUTPUT_FIELD_SEPARATOR $, + +# The input record separator (newline by default). This is the value +# that routines such as Kernel#gets use to determine record +# boundaries. If set to +nil+, +gets+ will read the entire file. +alias $RS $/ + +# The input record separator (newline by default). This is the value +# that routines such as Kernel#gets use to determine record +# boundaries. If set to +nil+, +gets+ will read the entire file. +alias $INPUT_RECORD_SEPARATOR $/ + +# The string appended to the output of every call to methods such as +# Kernel#print and IO#write. The default value is +nil+. +alias $ORS $\ + +# The string appended to the output of every call to methods such as +# Kernel#print and IO#write. The default value is +nil+. +alias $OUTPUT_RECORD_SEPARATOR $\ + +# The number of the last line read from the current input file. +alias $INPUT_LINE_NUMBER $. + +# The number of the last line read from the current input file. +alias $NR $. + +# The last line read by Kernel#gets or +# Kernel#readline. Many string-related functions in the +# Kernel module operate on $_ by default. The variable is +# local to the current scope. Thread local. +alias $LAST_READ_LINE $_ + +# The destination of output for Kernel#print +# and Kernel#printf. The default value is +# $stdout. +alias $DEFAULT_OUTPUT $> + +# An object that provides access to the concatenation +# of the contents of all the files +# given as command-line arguments, or $stdin +# (in the case where there are no +# arguments). $< supports methods similar to a +# File object: +# +inmode+, +close+, +# closed?, +each+, +# each_byte, each_line, +# +eof+, eof?, +file+, +# +filename+, +fileno+, +# +getc+, +gets+, +lineno+, +# lineno=, +path+, +# +pos+, pos=, +# +read+, +readchar+, +# +readline+, +readlines+, +# +rewind+, +seek+, +skip+, +# +tell+, to_a, to_i, +# to_io, to_s, along with the +# methods in Enumerable. The method +file+ +# returns a File object for the file currently +# being read. This may change as $< reads +# through the files on the command line. Read only. +alias $DEFAULT_INPUT $< + +# The process number of the program being executed. Read only. +alias $PID $$ + +# The process number of the program being executed. Read only. +alias $PROCESS_ID $$ + +# The exit status of the last child process to terminate. Read +# only. Thread local. +alias $CHILD_STATUS $? + +# A +MatchData+ object that encapsulates the results of a successful +# pattern match. The variables $&, $`, $', +# and $1 to $9 are all derived from +# $~. Assigning to $~ changes the values of these +# derived variables. This variable is local to the current +# scope. +alias $LAST_MATCH_INFO $~ + +# This variable is no longer effective. Deprecated. +alias $IGNORECASE $= + +# An array of strings containing the command-line +# options from the invocation of the program. Options +# used by the Ruby interpreter will have been +# removed. Read only. Also known simply as +ARGV+. +alias $ARGV $* + +# The string matched by the last successful pattern +# match. This variable is local to the current +# scope. Read only. +alias $MATCH $& + +# The string preceding the match in the last +# successful pattern match. This variable is local to +# the current scope. Read only. +alias $PREMATCH $` + +# The string following the match in the last +# successful pattern match. This variable is local to +# the current scope. Read only. +alias $POSTMATCH $' + +# The contents of the highest-numbered group matched in the last +# successful pattern match. Thus, in "cat" =~ /(c|a)(t|z)/, +# $+ will be set to "t". This variable is local to the +# current scope. Read only. +alias $LAST_PAREN_MATCH $+ diff --git a/games/FNaFB2/Ruby/stdlib/abbrev.rb b/games/FNaFB2/Ruby/stdlib/abbrev.rb new file mode 100644 index 0000000..2af01d2 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/abbrev.rb @@ -0,0 +1,132 @@ +# frozen_string_literal: true +#-- +# Copyright (c) 2001,2003 Akinori MUSHA +# +# All rights reserved. You can redistribute and/or modify it under +# the same terms as Ruby. +# +# $Idaemons: /home/cvs/rb/abbrev.rb,v 1.2 2001/05/30 09:37:45 knu Exp $ +# $RoughId: abbrev.rb,v 1.4 2003/10/14 19:45:42 knu Exp $ +# $Id$ +#++ + +## +# Calculates the set of unambiguous abbreviations for a given set of strings. +# +# require 'abbrev' +# require 'pp' +# +# pp Abbrev.abbrev(['ruby']) +# #=> {"ruby"=>"ruby", "rub"=>"ruby", "ru"=>"ruby", "r"=>"ruby"} +# +# pp Abbrev.abbrev(%w{ ruby rules }) +# +# _Generates:_ +# { "ruby" => "ruby", +# "rub" => "ruby", +# "rules" => "rules", +# "rule" => "rules", +# "rul" => "rules" } +# +# It also provides an array core extension, Array#abbrev. +# +# pp %w{ summer winter }.abbrev +# +# _Generates:_ +# { "summer" => "summer", +# "summe" => "summer", +# "summ" => "summer", +# "sum" => "summer", +# "su" => "summer", +# "s" => "summer", +# "winter" => "winter", +# "winte" => "winter", +# "wint" => "winter", +# "win" => "winter", +# "wi" => "winter", +# "w" => "winter" } + +module Abbrev + + # Given a set of strings, calculate the set of unambiguous abbreviations for + # those strings, and return a hash where the keys are all the possible + # abbreviations and the values are the full strings. + # + # Thus, given +words+ is "car" and "cone", the keys pointing to "car" would + # be "ca" and "car", while those pointing to "cone" would be "co", "con", and + # "cone". + # + # require 'abbrev' + # + # Abbrev.abbrev(%w{ car cone }) + # #=> {"ca"=>"car", "con"=>"cone", "co"=>"cone", "car"=>"car", "cone"=>"cone"} + # + # The optional +pattern+ parameter is a pattern or a string. Only input + # strings that match the pattern or start with the string are included in the + # output hash. + # + # Abbrev.abbrev(%w{car box cone crab}, /b/) + # #=> {"box"=>"box", "bo"=>"box", "b"=>"box", "crab" => "crab"} + # + # Abbrev.abbrev(%w{car box cone}, 'ca') + # #=> {"car"=>"car", "ca"=>"car"} + def abbrev(words, pattern = nil) + table = {} + seen = Hash.new(0) + + if pattern.is_a?(String) + pattern = /\A#{Regexp.quote(pattern)}/ # regard as a prefix + end + + words.each do |word| + next if word.empty? + word.size.downto(1) { |len| + abbrev = word[0...len] + + next if pattern && pattern !~ abbrev + + case seen[abbrev] += 1 + when 1 + table[abbrev] = word + when 2 + table.delete(abbrev) + else + break + end + } + end + + words.each do |word| + next if pattern && pattern !~ word + + table[word] = word + end + + table + end + + module_function :abbrev +end + +class Array + # Calculates the set of unambiguous abbreviations for the strings in +self+. + # + # require 'abbrev' + # %w{ car cone }.abbrev + # #=> {"car"=>"car", "ca"=>"car", "cone"=>"cone", "con"=>"cone", "co"=>"cone"} + # + # The optional +pattern+ parameter is a pattern or a string. Only input + # strings that match the pattern or start with the string are included in the + # output hash. + # + # %w{ fast boat day }.abbrev(/^.a/) + # #=> {"fast"=>"fast", "fas"=>"fast", "fa"=>"fast", "day"=>"day", "da"=>"day"} + # + # Abbrev.abbrev(%w{car box cone}, "ca") + # #=> {"car"=>"car", "ca"=>"car"} + # + # See also Abbrev.abbrev + def abbrev(pattern = nil) + Abbrev::abbrev(self, pattern) + end +end diff --git a/games/FNaFB2/Ruby/stdlib/base64.rb b/games/FNaFB2/Ruby/stdlib/base64.rb new file mode 100644 index 0000000..693aa1f --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/base64.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true +# +# = base64.rb: methods for base64-encoding and -decoding strings +# + +# The Base64 module provides for the encoding (#encode64, #strict_encode64, +# #urlsafe_encode64) and decoding (#decode64, #strict_decode64, +# #urlsafe_decode64) of binary data using a Base64 representation. +# +# == Example +# +# A simple encoding and decoding. +# +# require "base64" +# +# enc = Base64.encode64('Send reinforcements') +# # -> "U2VuZCByZWluZm9yY2VtZW50cw==\n" +# plain = Base64.decode64(enc) +# # -> "Send reinforcements" +# +# The purpose of using base64 to encode data is that it translates any +# binary data into purely printable characters. + +module Base64 + module_function + + # Returns the Base64-encoded version of +bin+. + # This method complies with RFC 2045. + # Line feeds are added to every 60 encoded characters. + # + # require 'base64' + # Base64.encode64("Now is the time for all good coders\nto learn Ruby") + # + # Generates: + # + # Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g + # UnVieQ== + def encode64(bin) + [bin].pack("m") + end + + # Returns the Base64-decoded version of +str+. + # This method complies with RFC 2045. + # Characters outside the base alphabet are ignored. + # + # require 'base64' + # str = 'VGhpcyBpcyBsaW5lIG9uZQpUaGlzIG' + + # 'lzIGxpbmUgdHdvClRoaXMgaXMgbGlu' + + # 'ZSB0aHJlZQpBbmQgc28gb24uLi4K' + # puts Base64.decode64(str) + # + # Generates: + # + # This is line one + # This is line two + # This is line three + # And so on... + def decode64(str) + str.unpack1("m") + end + + # Returns the Base64-encoded version of +bin+. + # This method complies with RFC 4648. + # No line feeds are added. + def strict_encode64(bin) + [bin].pack("m0") + end + + # Returns the Base64-decoded version of +str+. + # This method complies with RFC 4648. + # ArgumentError is raised if +str+ is incorrectly padded or contains + # non-alphabet characters. Note that CR or LF are also rejected. + def strict_decode64(str) + str.unpack1("m0") + end + + # Returns the Base64-encoded version of +bin+. + # This method complies with ``Base 64 Encoding with URL and Filename Safe + # Alphabet'' in RFC 4648. + # The alphabet uses '-' instead of '+' and '_' instead of '/'. + # Note that the result can still contain '='. + # You can remove the padding by setting +padding+ as false. + def urlsafe_encode64(bin, padding: true) + str = strict_encode64(bin) + str.chomp!("==") or str.chomp!("=") unless padding + str.tr!("+/", "-_") + str + end + + # Returns the Base64-decoded version of +str+. + # This method complies with ``Base 64 Encoding with URL and Filename Safe + # Alphabet'' in RFC 4648. + # The alphabet uses '-' instead of '+' and '_' instead of '/'. + # + # The padding character is optional. + # This method accepts both correctly-padded and unpadded input. + # Note that it still rejects incorrectly-padded input. + def urlsafe_decode64(str) + # NOTE: RFC 4648 does say nothing about unpadded input, but says that + # "the excess pad characters MAY also be ignored", so it is inferred that + # unpadded input is also acceptable. + if !str.end_with?("=") && str.length % 4 != 0 + str = str.ljust((str.length + 3) & ~3, "=") + str.tr!("-_", "+/") + else + str = str.tr("-_", "+/") + end + strict_decode64(str) + end +end diff --git a/games/FNaFB2/Ruby/stdlib/benchmark.rb b/games/FNaFB2/Ruby/stdlib/benchmark.rb new file mode 100644 index 0000000..79c782e --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/benchmark.rb @@ -0,0 +1,582 @@ +# frozen_string_literal: true +#-- +# benchmark.rb - a performance benchmarking library +# +# $Id$ +# +# Created by Gotoken (gotoken@notwork.org). +# +# Documentation by Gotoken (original RD), Lyle Johnson (RDoc conversion), and +# Gavin Sinclair (editing). +#++ +# +# == Overview +# +# The Benchmark module provides methods for benchmarking Ruby code, giving +# detailed reports on the time taken for each task. +# + +# The Benchmark module provides methods to measure and report the time +# used to execute Ruby code. +# +# * Measure the time to construct the string given by the expression +# "a"*1_000_000_000: +# +# require 'benchmark' +# +# puts Benchmark.measure { "a"*1_000_000_000 } +# +# On my machine (OSX 10.8.3 on i5 1.7 GHz) this generates: +# +# 0.350000 0.400000 0.750000 ( 0.835234) +# +# This report shows the user CPU time, system CPU time, the sum of +# the user and system CPU times, and the elapsed real time. The unit +# of time is seconds. +# +# * Do some experiments sequentially using the #bm method: +# +# require 'benchmark' +# +# n = 5000000 +# Benchmark.bm do |x| +# x.report { for i in 1..n; a = "1"; end } +# x.report { n.times do ; a = "1"; end } +# x.report { 1.upto(n) do ; a = "1"; end } +# end +# +# The result: +# +# user system total real +# 1.010000 0.000000 1.010000 ( 1.014479) +# 1.000000 0.000000 1.000000 ( 0.998261) +# 0.980000 0.000000 0.980000 ( 0.981335) +# +# * Continuing the previous example, put a label in each report: +# +# require 'benchmark' +# +# n = 5000000 +# Benchmark.bm(7) do |x| +# x.report("for:") { for i in 1..n; a = "1"; end } +# x.report("times:") { n.times do ; a = "1"; end } +# x.report("upto:") { 1.upto(n) do ; a = "1"; end } +# end +# +# The result: +# +# user system total real +# for: 1.010000 0.000000 1.010000 ( 1.015688) +# times: 1.000000 0.000000 1.000000 ( 1.003611) +# upto: 1.030000 0.000000 1.030000 ( 1.028098) +# +# * The times for some benchmarks depend on the order in which items +# are run. These differences are due to the cost of memory +# allocation and garbage collection. To avoid these discrepancies, +# the #bmbm method is provided. For example, to compare ways to +# sort an array of floats: +# +# require 'benchmark' +# +# array = (1..1000000).map { rand } +# +# Benchmark.bmbm do |x| +# x.report("sort!") { array.dup.sort! } +# x.report("sort") { array.dup.sort } +# end +# +# The result: +# +# Rehearsal ----------------------------------------- +# sort! 1.490000 0.010000 1.500000 ( 1.490520) +# sort 1.460000 0.000000 1.460000 ( 1.463025) +# -------------------------------- total: 2.960000sec +# +# user system total real +# sort! 1.460000 0.000000 1.460000 ( 1.460465) +# sort 1.450000 0.010000 1.460000 ( 1.448327) +# +# * Report statistics of sequential experiments with unique labels, +# using the #benchmark method: +# +# require 'benchmark' +# include Benchmark # we need the CAPTION and FORMAT constants +# +# n = 5000000 +# Benchmark.benchmark(CAPTION, 7, FORMAT, ">total:", ">avg:") do |x| +# tf = x.report("for:") { for i in 1..n; a = "1"; end } +# tt = x.report("times:") { n.times do ; a = "1"; end } +# tu = x.report("upto:") { 1.upto(n) do ; a = "1"; end } +# [tf+tt+tu, (tf+tt+tu)/3] +# end +# +# The result: +# +# user system total real +# for: 0.950000 0.000000 0.950000 ( 0.952039) +# times: 0.980000 0.000000 0.980000 ( 0.984938) +# upto: 0.950000 0.000000 0.950000 ( 0.946787) +# >total: 2.880000 0.000000 2.880000 ( 2.883764) +# >avg: 0.960000 0.000000 0.960000 ( 0.961255) + +module Benchmark + + BENCHMARK_VERSION = "2002-04-25" # :nodoc: + + # Invokes the block with a Benchmark::Report object, which + # may be used to collect and report on the results of individual + # benchmark tests. Reserves +label_width+ leading spaces for + # labels on each line. Prints +caption+ at the top of the + # report, and uses +format+ to format each line. + # (Note: +caption+ must contain a terminating newline character, + # see the default Benchmark::Tms::CAPTION for an example.) + # + # Returns an array of Benchmark::Tms objects. + # + # If the block returns an array of + # Benchmark::Tms objects, these will be used to format + # additional lines of output. If +labels+ parameter are + # given, these are used to label these extra lines. + # + # _Note_: Other methods provide a simpler interface to this one, and are + # suitable for nearly all benchmarking requirements. See the examples in + # Benchmark, and the #bm and #bmbm methods. + # + # Example: + # + # require 'benchmark' + # include Benchmark # we need the CAPTION and FORMAT constants + # + # n = 5000000 + # Benchmark.benchmark(CAPTION, 7, FORMAT, ">total:", ">avg:") do |x| + # tf = x.report("for:") { for i in 1..n; a = "1"; end } + # tt = x.report("times:") { n.times do ; a = "1"; end } + # tu = x.report("upto:") { 1.upto(n) do ; a = "1"; end } + # [tf+tt+tu, (tf+tt+tu)/3] + # end + # + # Generates: + # + # user system total real + # for: 0.970000 0.000000 0.970000 ( 0.970493) + # times: 0.990000 0.000000 0.990000 ( 0.989542) + # upto: 0.970000 0.000000 0.970000 ( 0.972854) + # >total: 2.930000 0.000000 2.930000 ( 2.932889) + # >avg: 0.976667 0.000000 0.976667 ( 0.977630) + # + + def benchmark(caption = "", label_width = nil, format = nil, *labels) # :yield: report + sync = $stdout.sync + $stdout.sync = true + label_width ||= 0 + label_width += 1 + format ||= FORMAT + print ' '*label_width + caption unless caption.empty? + report = Report.new(label_width, format) + results = yield(report) + Array === results and results.grep(Tms).each {|t| + print((labels.shift || t.label || "").ljust(label_width), t.format(format)) + } + report.list + ensure + $stdout.sync = sync unless sync.nil? + end + + + # A simple interface to the #benchmark method, #bm generates sequential + # reports with labels. +label_width+ and +labels+ parameters have the same + # meaning as for #benchmark. + # + # require 'benchmark' + # + # n = 5000000 + # Benchmark.bm(7) do |x| + # x.report("for:") { for i in 1..n; a = "1"; end } + # x.report("times:") { n.times do ; a = "1"; end } + # x.report("upto:") { 1.upto(n) do ; a = "1"; end } + # end + # + # Generates: + # + # user system total real + # for: 0.960000 0.000000 0.960000 ( 0.957966) + # times: 0.960000 0.000000 0.960000 ( 0.960423) + # upto: 0.950000 0.000000 0.950000 ( 0.954864) + # + + def bm(label_width = 0, *labels, &blk) # :yield: report + benchmark(CAPTION, label_width, FORMAT, *labels, &blk) + end + + + # Sometimes benchmark results are skewed because code executed + # earlier encounters different garbage collection overheads than + # that run later. #bmbm attempts to minimize this effect by running + # the tests twice, the first time as a rehearsal in order to get the + # runtime environment stable, the second time for + # real. GC.start is executed before the start of each of + # the real timings; the cost of this is not included in the + # timings. In reality, though, there's only so much that #bmbm can + # do, and the results are not guaranteed to be isolated from garbage + # collection and other effects. + # + # Because #bmbm takes two passes through the tests, it can + # calculate the required label width. + # + # require 'benchmark' + # + # array = (1..1000000).map { rand } + # + # Benchmark.bmbm do |x| + # x.report("sort!") { array.dup.sort! } + # x.report("sort") { array.dup.sort } + # end + # + # Generates: + # + # Rehearsal ----------------------------------------- + # sort! 1.440000 0.010000 1.450000 ( 1.446833) + # sort 1.440000 0.000000 1.440000 ( 1.448257) + # -------------------------------- total: 2.890000sec + # + # user system total real + # sort! 1.460000 0.000000 1.460000 ( 1.458065) + # sort 1.450000 0.000000 1.450000 ( 1.455963) + # + # #bmbm yields a Benchmark::Job object and returns an array of + # Benchmark::Tms objects. + # + def bmbm(width = 0) # :yield: job + job = Job.new(width) + yield(job) + width = job.width + 1 + sync = $stdout.sync + $stdout.sync = true + + # rehearsal + puts 'Rehearsal '.ljust(width+CAPTION.length,'-') + ets = job.list.inject(Tms.new) { |sum,(label,item)| + print label.ljust(width) + res = Benchmark.measure(&item) + print res.format + sum + res + }.format("total: %tsec") + print " #{ets}\n\n".rjust(width+CAPTION.length+2,'-') + + # take + print ' '*width + CAPTION + job.list.map { |label,item| + GC.start + print label.ljust(width) + Benchmark.measure(label, &item).tap { |res| print res } + } + ensure + $stdout.sync = sync unless sync.nil? + end + + # + # Returns the time used to execute the given block as a + # Benchmark::Tms object. Takes +label+ option. + # + # require 'benchmark' + # + # n = 1000000 + # + # time = Benchmark.measure do + # n.times { a = "1" } + # end + # puts time + # + # Generates: + # + # 0.220000 0.000000 0.220000 ( 0.227313) + # + def measure(label = "") # :yield: + t0, r0 = Process.times, Process.clock_gettime(Process::CLOCK_MONOTONIC) + yield + t1, r1 = Process.times, Process.clock_gettime(Process::CLOCK_MONOTONIC) + Benchmark::Tms.new(t1.utime - t0.utime, + t1.stime - t0.stime, + t1.cutime - t0.cutime, + t1.cstime - t0.cstime, + r1 - r0, + label) + end + + # + # Returns the elapsed real time used to execute the given block. + # + def realtime # :yield: + r0 = Process.clock_gettime(Process::CLOCK_MONOTONIC) + yield + Process.clock_gettime(Process::CLOCK_MONOTONIC) - r0 + end + + module_function :benchmark, :measure, :realtime, :bm, :bmbm + + # + # A Job is a sequence of labelled blocks to be processed by the + # Benchmark.bmbm method. It is of little direct interest to the user. + # + class Job # :nodoc: + # + # Returns an initialized Job instance. + # Usually, one doesn't call this method directly, as new + # Job objects are created by the #bmbm method. + # +width+ is a initial value for the label offset used in formatting; + # the #bmbm method passes its +width+ argument to this constructor. + # + def initialize(width) + @width = width + @list = [] + end + + # + # Registers the given label and block pair in the job list. + # + def item(label = "", &blk) # :yield: + raise ArgumentError, "no block" unless block_given? + label = label.to_s + w = label.length + @width = w if @width < w + @list << [label, blk] + self + end + + alias report item + + # An array of 2-element arrays, consisting of label and block pairs. + attr_reader :list + + # Length of the widest label in the #list. + attr_reader :width + end + + # + # This class is used by the Benchmark.benchmark and Benchmark.bm methods. + # It is of little direct interest to the user. + # + class Report # :nodoc: + # + # Returns an initialized Report instance. + # Usually, one doesn't call this method directly, as new + # Report objects are created by the #benchmark and #bm methods. + # +width+ and +format+ are the label offset and + # format string used by Tms#format. + # + def initialize(width = 0, format = nil) + @width, @format, @list = width, format, [] + end + + # + # Prints the +label+ and measured time for the block, + # formatted by +format+. See Tms#format for the + # formatting rules. + # + def item(label = "", *format, &blk) # :yield: + print label.to_s.ljust(@width) + @list << res = Benchmark.measure(label, &blk) + print res.format(@format, *format) + res + end + + alias report item + + # An array of Benchmark::Tms objects representing each item. + attr_reader :list + end + + + + # + # A data object, representing the times associated with a benchmark + # measurement. + # + class Tms + + # Default caption, see also Benchmark::CAPTION + CAPTION = " user system total real\n" + + # Default format string, see also Benchmark::FORMAT + FORMAT = "%10.6u %10.6y %10.6t %10.6r\n" + + # User CPU time + attr_reader :utime + + # System CPU time + attr_reader :stime + + # User CPU time of children + attr_reader :cutime + + # System CPU time of children + attr_reader :cstime + + # Elapsed real time + attr_reader :real + + # Total time, that is +utime+ + +stime+ + +cutime+ + +cstime+ + attr_reader :total + + # Label + attr_reader :label + + # + # Returns an initialized Tms object which has + # +utime+ as the user CPU time, +stime+ as the system CPU time, + # +cutime+ as the children's user CPU time, +cstime+ as the children's + # system CPU time, +real+ as the elapsed real time and +label+ as the label. + # + def initialize(utime = 0.0, stime = 0.0, cutime = 0.0, cstime = 0.0, real = 0.0, label = nil) + @utime, @stime, @cutime, @cstime, @real, @label = utime, stime, cutime, cstime, real, label.to_s + @total = @utime + @stime + @cutime + @cstime + end + + # + # Returns a new Tms object whose times are the sum of the times for this + # Tms object, plus the time required to execute the code block (+blk+). + # + def add(&blk) # :yield: + self + Benchmark.measure(&blk) + end + + # + # An in-place version of #add. + # Changes the times of this Tms object by making it the sum of the times + # for this Tms object, plus the time required to execute + # the code block (+blk+). + # + def add!(&blk) + t = Benchmark.measure(&blk) + @utime = utime + t.utime + @stime = stime + t.stime + @cutime = cutime + t.cutime + @cstime = cstime + t.cstime + @real = real + t.real + self + end + + # + # Returns a new Tms object obtained by memberwise summation + # of the individual times for this Tms object with those of the +other+ + # Tms object. + # This method and #/() are useful for taking statistics. + # + def +(other); memberwise(:+, other) end + + # + # Returns a new Tms object obtained by memberwise subtraction + # of the individual times for the +other+ Tms object from those of this + # Tms object. + # + def -(other); memberwise(:-, other) end + + # + # Returns a new Tms object obtained by memberwise multiplication + # of the individual times for this Tms object by +x+. + # + def *(x); memberwise(:*, x) end + + # + # Returns a new Tms object obtained by memberwise division + # of the individual times for this Tms object by +x+. + # This method and #+() are useful for taking statistics. + # + def /(x); memberwise(:/, x) end + + # + # Returns the contents of this Tms object as + # a formatted string, according to a +format+ string + # like that passed to Kernel.format. In addition, #format + # accepts the following extensions: + # + # %u:: Replaced by the user CPU time, as reported by Tms#utime. + # %y:: Replaced by the system CPU time, as reported by #stime (Mnemonic: y of "s*y*stem") + # %U:: Replaced by the children's user CPU time, as reported by Tms#cutime + # %Y:: Replaced by the children's system CPU time, as reported by Tms#cstime + # %t:: Replaced by the total CPU time, as reported by Tms#total + # %r:: Replaced by the elapsed real time, as reported by Tms#real + # %n:: Replaced by the label string, as reported by Tms#label (Mnemonic: n of "*n*ame") + # + # If +format+ is not given, FORMAT is used as default value, detailing the + # user, system and real elapsed time. + # + def format(format = nil, *args) + str = (format || FORMAT).dup + str.gsub!(/(%[-+.\d]*)n/) { "#{$1}s" % label } + str.gsub!(/(%[-+.\d]*)u/) { "#{$1}f" % utime } + str.gsub!(/(%[-+.\d]*)y/) { "#{$1}f" % stime } + str.gsub!(/(%[-+.\d]*)U/) { "#{$1}f" % cutime } + str.gsub!(/(%[-+.\d]*)Y/) { "#{$1}f" % cstime } + str.gsub!(/(%[-+.\d]*)t/) { "#{$1}f" % total } + str.gsub!(/(%[-+.\d]*)r/) { "(#{$1}f)" % real } + format ? str % args : str + end + + # + # Same as #format. + # + def to_s + format + end + + # + # Returns a new 6-element array, consisting of the + # label, user CPU time, system CPU time, children's + # user CPU time, children's system CPU time and elapsed + # real time. + # + def to_a + [@label, @utime, @stime, @cutime, @cstime, @real] + end + + # + # Returns a hash containing the same data as `to_a`. + # + def to_h + { + label: @label, + utime: @utime, + stime: @stime, + cutime: @cutime, + cstime: @cstime, + real: @real + } + end + + protected + + # + # Returns a new Tms object obtained by memberwise operation +op+ + # of the individual times for this Tms object with those of the other + # Tms object (+x+). + # + # +op+ can be a mathematical operation such as +, -, + # *, / + # + def memberwise(op, x) + case x + when Benchmark::Tms + Benchmark::Tms.new(utime.__send__(op, x.utime), + stime.__send__(op, x.stime), + cutime.__send__(op, x.cutime), + cstime.__send__(op, x.cstime), + real.__send__(op, x.real) + ) + else + Benchmark::Tms.new(utime.__send__(op, x), + stime.__send__(op, x), + cutime.__send__(op, x), + cstime.__send__(op, x), + real.__send__(op, x) + ) + end + end + end + + # The default caption string (heading above the output times). + CAPTION = Benchmark::Tms::CAPTION + + # The default format string used to display times. See also Benchmark::Tms#format. + FORMAT = Benchmark::Tms::FORMAT +end diff --git a/games/FNaFB2/Ruby/stdlib/benchmark/version.rb b/games/FNaFB2/Ruby/stdlib/benchmark/version.rb new file mode 100644 index 0000000..545575f --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/benchmark/version.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true +module Benchmark + VERSION = "0.2.0" +end diff --git a/games/FNaFB2/Ruby/stdlib/bigdecimal.rb b/games/FNaFB2/Ruby/stdlib/bigdecimal.rb new file mode 100644 index 0000000..8fd2587 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bigdecimal.rb @@ -0,0 +1 @@ +require 'bigdecimal.so' diff --git a/games/FNaFB2/Ruby/stdlib/bigdecimal/jacobian.rb b/games/FNaFB2/Ruby/stdlib/bigdecimal/jacobian.rb new file mode 100644 index 0000000..5e29304 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bigdecimal/jacobian.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: false + +require 'bigdecimal' + +# require 'bigdecimal/jacobian' +# +# Provides methods to compute the Jacobian matrix of a set of equations at a +# point x. In the methods below: +# +# f is an Object which is used to compute the Jacobian matrix of the equations. +# It must provide the following methods: +# +# f.values(x):: returns the values of all functions at x +# +# f.zero:: returns 0.0 +# f.one:: returns 1.0 +# f.two:: returns 2.0 +# f.ten:: returns 10.0 +# +# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal. +# +# x is the point at which to compute the Jacobian. +# +# fx is f.values(x). +# +module Jacobian + module_function + + # Determines the equality of two numbers by comparing to zero, or using the epsilon value + def isEqual(a,b,zero=0.0,e=1.0e-8) + aa = a.abs + bb = b.abs + if aa == zero && bb == zero then + true + else + if ((a-b)/(aa+bb)).abs < e then + true + else + false + end + end + end + + + # Computes the derivative of f[i] at x[i]. + # fx is the value of f at x. + def dfdxi(f,fx,x,i) + nRetry = 0 + n = x.size + xSave = x[i] + ok = 0 + ratio = f.ten*f.ten*f.ten + dx = x[i].abs/ratio + dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps) + dx = f.one/f.ten if isEqual(dx,f.zero,f.zero,f.eps) + until ok>0 do + deriv = [] + nRetry += 1 + if nRetry > 100 + raise "Singular Jacobian matrix. No change at x[" + i.to_s + "]" + end + dx = dx*f.two + x[i] += dx + fxNew = f.values(x) + for j in 0...n do + if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then + ok += 1 + deriv <<= (fxNew[j]-fx[j])/dx + else + deriv <<= f.zero + end + end + x[i] = xSave + end + deriv + end + + # Computes the Jacobian of f at x. fx is the value of f at x. + def jacobian(f,fx,x) + n = x.size + dfdx = Array.new(n*n) + for i in 0...n do + df = dfdxi(f,fx,x,i) + for j in 0...n do + dfdx[j*n+i] = df[j] + end + end + dfdx + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bigdecimal/ludcmp.rb b/games/FNaFB2/Ruby/stdlib/bigdecimal/ludcmp.rb new file mode 100644 index 0000000..dd265e4 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bigdecimal/ludcmp.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: false +require 'bigdecimal' + +# +# Solves a*x = b for x, using LU decomposition. +# +module LUSolve + module_function + + # Performs LU decomposition of the n by n matrix a. + def ludecomp(a,n,zero=0,one=1) + prec = BigDecimal.limit(nil) + ps = [] + scales = [] + for i in 0...n do # pick up largest(abs. val.) element in each row. + ps <<= i + nrmrow = zero + ixn = i*n + for j in 0...n do + biggst = a[ixn+j].abs + nrmrow = biggst if biggst>nrmrow + end + if nrmrow>zero then + scales <<= one.div(nrmrow,prec) + else + raise "Singular matrix" + end + end + n1 = n - 1 + for k in 0...n1 do # Gaussian elimination with partial pivoting. + biggst = zero; + for i in k...n do + size = a[ps[i]*n+k].abs*scales[ps[i]] + if size>biggst then + biggst = size + pividx = i + end + end + raise "Singular matrix" if biggst<=zero + if pividx!=k then + j = ps[k] + ps[k] = ps[pividx] + ps[pividx] = j + end + pivot = a[ps[k]*n+k] + for i in (k+1)...n do + psin = ps[i]*n + a[psin+k] = mult = a[psin+k].div(pivot,prec) + if mult!=zero then + pskn = ps[k]*n + for j in (k+1)...n do + a[psin+j] -= mult.mult(a[pskn+j],prec) + end + end + end + end + raise "Singular matrix" if a[ps[n1]*n+n1] == zero + ps + end + + # Solves a*x = b for x, using LU decomposition. + # + # a is a matrix, b is a constant vector, x is the solution vector. + # + # ps is the pivot, a vector which indicates the permutation of rows performed + # during LU decomposition. + def lusolve(a,b,ps,zero=0.0) + prec = BigDecimal.limit(nil) + n = ps.size + x = [] + for i in 0...n do + dot = zero + psin = ps[i]*n + for j in 0...i do + dot = a[psin+j].mult(x[j],prec) + dot + end + x <<= b[ps[i]] - dot + end + (n-1).downto(0) do |i| + dot = zero + psin = ps[i]*n + for j in (i+1)...n do + dot = a[psin+j].mult(x[j],prec) + dot + end + x[i] = (x[i]-dot).div(a[psin+i],prec) + end + x + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bigdecimal/math.rb b/games/FNaFB2/Ruby/stdlib/bigdecimal/math.rb new file mode 100644 index 0000000..0b9d064 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bigdecimal/math.rb @@ -0,0 +1,232 @@ +# frozen_string_literal: false +require 'bigdecimal' + +# +#-- +# Contents: +# sqrt(x, prec) +# sin (x, prec) +# cos (x, prec) +# atan(x, prec) Note: |x|<1, x=0.9999 may not converge. +# PI (prec) +# E (prec) == exp(1.0,prec) +# +# where: +# x ... BigDecimal number to be computed. +# |x| must be small enough to get convergence. +# prec ... Number of digits to be obtained. +#++ +# +# Provides mathematical functions. +# +# Example: +# +# require "bigdecimal/math" +# +# include BigMath +# +# a = BigDecimal((PI(100)/2).to_s) +# puts sin(a,100) # => 0.99999999999999999999......e0 +# +module BigMath + module_function + + # call-seq: + # sqrt(decimal, numeric) -> BigDecimal + # + # Computes the square root of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # BigMath.sqrt(BigDecimal('2'), 16).to_s + # #=> "0.1414213562373095048801688724e1" + # + def sqrt(x, prec) + x.sqrt(prec) + end + + # call-seq: + # sin(decimal, numeric) -> BigDecimal + # + # Computes the sine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is Infinity or NaN, returns NaN. + # + # BigMath.sin(BigMath.PI(5)/4, 5).to_s + # #=> "0.70710678118654752440082036563292800375e0" + # + def sin(x, prec) + raise ArgumentError, "Zero or negative precision for sin" if prec <= 0 + return BigDecimal("NaN") if x.infinite? || x.nan? + n = prec + BigDecimal.double_fig + one = BigDecimal("1") + two = BigDecimal("2") + x = -x if neg = x < 0 + if x > (twopi = two * BigMath.PI(prec)) + if x > 30 + x %= twopi + else + x -= twopi while x > twopi + end + end + x1 = x + x2 = x.mult(x,n) + sign = 1 + y = x + d = y + i = one + z = one + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + sign = -sign + x1 = x2.mult(x1,n) + i += two + z *= (i-one) * i + d = sign * x1.div(z,m) + y += d + end + neg ? -y : y + end + + # call-seq: + # cos(decimal, numeric) -> BigDecimal + # + # Computes the cosine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is Infinity or NaN, returns NaN. + # + # BigMath.cos(BigMath.PI(4), 16).to_s + # #=> "-0.999999999999999999999999999999856613163740061349e0" + # + def cos(x, prec) + raise ArgumentError, "Zero or negative precision for cos" if prec <= 0 + return BigDecimal("NaN") if x.infinite? || x.nan? + n = prec + BigDecimal.double_fig + one = BigDecimal("1") + two = BigDecimal("2") + x = -x if x < 0 + if x > (twopi = two * BigMath.PI(prec)) + if x > 30 + x %= twopi + else + x -= twopi while x > twopi + end + end + x1 = one + x2 = x.mult(x,n) + sign = 1 + y = one + d = y + i = BigDecimal("0") + z = one + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + sign = -sign + x1 = x2.mult(x1,n) + i += two + z *= (i-one) * i + d = sign * x1.div(z,m) + y += d + end + y + end + + # call-seq: + # atan(decimal, numeric) -> BigDecimal + # + # Computes the arctangent of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.atan(BigDecimal('-1'), 16).to_s + # #=> "-0.785398163397448309615660845819878471907514682065e0" + # + def atan(x, prec) + raise ArgumentError, "Zero or negative precision for atan" if prec <= 0 + return BigDecimal("NaN") if x.nan? + pi = PI(prec) + x = -x if neg = x < 0 + return pi.div(neg ? -2 : 2, prec) if x.infinite? + return pi / (neg ? -4 : 4) if x.round(prec) == 1 + x = BigDecimal("1").div(x, prec) if inv = x > 1 + x = (-1 + sqrt(1 + x**2, prec))/x if dbl = x > 0.5 + n = prec + BigDecimal.double_fig + y = x + d = y + t = x + r = BigDecimal("3") + x2 = x.mult(x,n) + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + t = -t.mult(x2,n) + d = t.div(r,m) + y += d + r += 2 + end + y *= 2 if dbl + y = pi / 2 - y if inv + y = -y if neg + y + end + + # call-seq: + # PI(numeric) -> BigDecimal + # + # Computes the value of pi to the specified number of digits of precision, + # +numeric+. + # + # BigMath.PI(10).to_s + # #=> "0.3141592653589793238462643388813853786957412e1" + # + def PI(prec) + raise ArgumentError, "Zero or negative precision for PI" if prec <= 0 + n = prec + BigDecimal.double_fig + zero = BigDecimal("0") + one = BigDecimal("1") + two = BigDecimal("2") + + m25 = BigDecimal("-0.04") + m57121 = BigDecimal("-57121") + + pi = zero + + d = one + k = one + t = BigDecimal("-80") + while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + t = t*m25 + d = t.div(k,m) + k = k+two + pi = pi + d + end + + d = one + k = one + t = BigDecimal("956") + while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + t = t.div(m57121,n) + d = t.div(k,m) + pi = pi + d + k = k+two + end + pi + end + + # call-seq: + # E(numeric) -> BigDecimal + # + # Computes e (the base of natural logarithms) to the specified number of + # digits of precision, +numeric+. + # + # BigMath.E(10).to_s + # #=> "0.271828182845904523536028752390026306410273e1" + # + def E(prec) + raise ArgumentError, "Zero or negative precision for E" if prec <= 0 + BigMath.exp(1, prec) + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bigdecimal/newton.rb b/games/FNaFB2/Ruby/stdlib/bigdecimal/newton.rb new file mode 100644 index 0000000..85bacb7 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bigdecimal/newton.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: false +require "bigdecimal/ludcmp" +require "bigdecimal/jacobian" + +# +# newton.rb +# +# Solves the nonlinear algebraic equation system f = 0 by Newton's method. +# This program is not dependent on BigDecimal. +# +# To call: +# n = nlsolve(f,x) +# where n is the number of iterations required, +# x is the initial value vector +# f is an Object which is used to compute the values of the equations to be solved. +# It must provide the following methods: +# +# f.values(x):: returns the values of all functions at x +# +# f.zero:: returns 0.0 +# f.one:: returns 1.0 +# f.two:: returns 2.0 +# f.ten:: returns 10.0 +# +# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal. +# +# On exit, x is the solution vector. +# +module Newton + include LUSolve + include Jacobian + module_function + + def norm(fv,zero=0.0) # :nodoc: + s = zero + n = fv.size + for i in 0...n do + s += fv[i]*fv[i] + end + s + end + + # See also Newton + def nlsolve(f,x) + nRetry = 0 + n = x.size + + f0 = f.values(x) + zero = f.zero + one = f.one + two = f.two + p5 = one/two + d = norm(f0,zero) + minfact = f.ten*f.ten*f.ten + minfact = one/minfact + e = f.eps + while d >= e do + nRetry += 1 + # Not yet converged. => Compute Jacobian matrix + dfdx = jacobian(f,f0,x) + # Solve dfdx*dx = -f0 to estimate dx + dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero) + fact = two + xs = x.dup + begin + fact *= p5 + if fact < minfact then + raise "Failed to reduce function values." + end + for i in 0...n do + x[i] = xs[i] - dx[i]*fact + end + f0 = f.values(x) + dn = norm(f0,zero) + end while(dn>=d) + d = dn + end + nRetry + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bigdecimal/util.rb b/games/FNaFB2/Ruby/stdlib/bigdecimal/util.rb new file mode 100644 index 0000000..cb645d2 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bigdecimal/util.rb @@ -0,0 +1,181 @@ +# frozen_string_literal: false +# +#-- +# bigdecimal/util extends various native classes to provide the #to_d method, +# and provides BigDecimal#to_d and BigDecimal#to_digits. +#++ + +require 'bigdecimal' + +class Integer < Numeric + # call-seq: + # int.to_d -> bigdecimal + # + # Returns the value of +int+ as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # 42.to_d # => 0.42e2 + # + # See also BigDecimal::new. + # + def to_d + BigDecimal(self) + end +end + + +class Float < Numeric + # call-seq: + # float.to_d -> bigdecimal + # float.to_d(precision) -> bigdecimal + # + # Returns the value of +float+ as a BigDecimal. + # The +precision+ parameter is used to determine the number of + # significant digits for the result (the default is Float::DIG). + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # 0.5.to_d # => 0.5e0 + # 1.234.to_d(2) # => 0.12e1 + # + # See also BigDecimal::new. + # + def to_d(precision=0) + BigDecimal(self, precision) + end +end + + +class String + # call-seq: + # str.to_d -> bigdecimal + # + # Returns the result of interpreting leading characters in +str+ + # as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # "0.5".to_d # => 0.5e0 + # "123.45e1".to_d # => 0.12345e4 + # "45.67 degrees".to_d # => 0.4567e2 + # + # See also BigDecimal::new. + # + def to_d + BigDecimal.interpret_loosely(self) + end +end + + +class BigDecimal < Numeric + # call-seq: + # a.to_digits -> string + # + # Converts a BigDecimal to a String of the form "nnnnnn.mmm". + # This method is deprecated; use BigDecimal#to_s("F") instead. + # + # require 'bigdecimal/util' + # + # d = BigDecimal("3.14") + # d.to_digits # => "3.14" + # + def to_digits + if self.nan? || self.infinite? || self.zero? + self.to_s + else + i = self.to_i.to_s + _,f,_,z = self.frac.split + i + "." + ("0"*(-z)) + f + end + end + + # call-seq: + # a.to_d -> bigdecimal + # + # Returns self. + # + # require 'bigdecimal/util' + # + # d = BigDecimal("3.14") + # d.to_d # => 0.314e1 + # + def to_d + self + end +end + + +class Rational < Numeric + # call-seq: + # rat.to_d(precision) -> bigdecimal + # + # Returns the value as a BigDecimal. + # + # The required +precision+ parameter is used to determine the number of + # significant digits for the result. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # Rational(22, 7).to_d(3) # => 0.314e1 + # + # See also BigDecimal::new. + # + def to_d(precision) + BigDecimal(self, precision) + end +end + + +class Complex < Numeric + # call-seq: + # cmp.to_d -> bigdecimal + # cmp.to_d(precision) -> bigdecimal + # + # Returns the value as a BigDecimal. + # + # The +precision+ parameter is required for a rational complex number. + # This parameter is used to determine the number of significant digits + # for the result. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # Complex(0.1234567, 0).to_d(4) # => 0.1235e0 + # Complex(Rational(22, 7), 0).to_d(3) # => 0.314e1 + # + # See also BigDecimal::new. + # + def to_d(*args) + BigDecimal(self) unless self.imag.zero? # to raise eerror + + if args.length == 0 + case self.real + when Rational + BigDecimal(self.real) # to raise error + end + end + self.real.to_d(*args) + end +end + + +class NilClass + # call-seq: + # nil.to_d -> bigdecimal + # + # Returns nil represented as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # nil.to_d # => 0.0 + # + def to_d + BigDecimal(0) + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler.rb b/games/FNaFB2/Ruby/stdlib/bundler.rb new file mode 100644 index 0000000..436cdf2 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler.rb @@ -0,0 +1,713 @@ +# frozen_string_literal: true + +require_relative "bundler/vendored_fileutils" +require "pathname" +require "rbconfig" + +require_relative "bundler/errors" +require_relative "bundler/environment_preserver" +require_relative "bundler/plugin" +require_relative "bundler/rubygems_ext" +require_relative "bundler/rubygems_integration" +require_relative "bundler/version" +require_relative "bundler/constants" +require_relative "bundler/current_ruby" +require_relative "bundler/build_metadata" + +# Bundler provides a consistent environment for Ruby projects by +# tracking and installing the exact gems and versions that are needed. +# +# Since Ruby 2.6, Bundler is a part of Ruby's standard library. +# +# Bundler is used by creating _gemfiles_ listing all the project dependencies +# and (optionally) their versions and then using +# +# require 'bundler/setup' +# +# or Bundler.setup to setup environment where only specified gems and their +# specified versions could be used. +# +# See {Bundler website}[https://bundler.io/docs.html] for extensive documentation +# on gemfiles creation and Bundler usage. +# +# As a standard library inside project, Bundler could be used for introspection +# of loaded and required modules. +# +module Bundler + environment_preserver = EnvironmentPreserver.from_env + ORIGINAL_ENV = environment_preserver.restore + environment_preserver.replace_with_backup + SUDO_MUTEX = Thread::Mutex.new + + autoload :Definition, File.expand_path("bundler/definition", __dir__) + autoload :Dependency, File.expand_path("bundler/dependency", __dir__) + autoload :Deprecate, File.expand_path("bundler/deprecate", __dir__) + autoload :Digest, File.expand_path("bundler/digest", __dir__) + autoload :Dsl, File.expand_path("bundler/dsl", __dir__) + autoload :EndpointSpecification, File.expand_path("bundler/endpoint_specification", __dir__) + autoload :Env, File.expand_path("bundler/env", __dir__) + autoload :Fetcher, File.expand_path("bundler/fetcher", __dir__) + autoload :FeatureFlag, File.expand_path("bundler/feature_flag", __dir__) + autoload :GemHelper, File.expand_path("bundler/gem_helper", __dir__) + autoload :GemHelpers, File.expand_path("bundler/gem_helpers", __dir__) + autoload :GemVersionPromoter, File.expand_path("bundler/gem_version_promoter", __dir__) + autoload :Graph, File.expand_path("bundler/graph", __dir__) + autoload :Index, File.expand_path("bundler/index", __dir__) + autoload :Injector, File.expand_path("bundler/injector", __dir__) + autoload :Installer, File.expand_path("bundler/installer", __dir__) + autoload :LazySpecification, File.expand_path("bundler/lazy_specification", __dir__) + autoload :LockfileParser, File.expand_path("bundler/lockfile_parser", __dir__) + autoload :MatchRemoteMetadata, File.expand_path("bundler/match_remote_metadata", __dir__) + autoload :ProcessLock, File.expand_path("bundler/process_lock", __dir__) + autoload :RemoteSpecification, File.expand_path("bundler/remote_specification", __dir__) + autoload :Resolver, File.expand_path("bundler/resolver", __dir__) + autoload :Retry, File.expand_path("bundler/retry", __dir__) + autoload :RubyDsl, File.expand_path("bundler/ruby_dsl", __dir__) + autoload :RubyVersion, File.expand_path("bundler/ruby_version", __dir__) + autoload :Runtime, File.expand_path("bundler/runtime", __dir__) + autoload :SelfManager, File.expand_path("bundler/self_manager", __dir__) + autoload :Settings, File.expand_path("bundler/settings", __dir__) + autoload :SharedHelpers, File.expand_path("bundler/shared_helpers", __dir__) + autoload :Source, File.expand_path("bundler/source", __dir__) + autoload :SourceList, File.expand_path("bundler/source_list", __dir__) + autoload :SourceMap, File.expand_path("bundler/source_map", __dir__) + autoload :SpecSet, File.expand_path("bundler/spec_set", __dir__) + autoload :StubSpecification, File.expand_path("bundler/stub_specification", __dir__) + autoload :UI, File.expand_path("bundler/ui", __dir__) + autoload :URICredentialsFilter, File.expand_path("bundler/uri_credentials_filter", __dir__) + autoload :VersionRanges, File.expand_path("bundler/version_ranges", __dir__) + + class << self + def configure + @configured ||= configure_gem_home_and_path + end + + def ui + (defined?(@ui) && @ui) || (self.ui = UI::Shell.new) + end + + def ui=(ui) + Bundler.rubygems.ui = UI::RGProxy.new(ui) + @ui = ui + end + + # Returns absolute path of where gems are installed on the filesystem. + def bundle_path + @bundle_path ||= Pathname.new(configured_bundle_path.path).expand_path(root) + end + + def create_bundle_path + SharedHelpers.filesystem_access(bundle_path.to_s) do |p| + mkdir_p(p) + end unless bundle_path.exist? + + @bundle_path = bundle_path.realpath + rescue Errno::EEXIST + raise PathError, "Could not install to path `#{bundle_path}` " \ + "because a file already exists at that path. Either remove or rename the file so the directory can be created." + end + + def configured_bundle_path + @configured_bundle_path ||= settings.path.tap(&:validate!) + end + + # Returns absolute location of where binstubs are installed to. + def bin_path + @bin_path ||= begin + path = settings[:bin] || "bin" + path = Pathname.new(path).expand_path(root).expand_path + SharedHelpers.filesystem_access(path) {|p| FileUtils.mkdir_p(p) } + path + end + end + + # Turns on the Bundler runtime. After +Bundler.setup+ call, all +load+ or + # +require+ of the gems would be allowed only if they are part of + # the Gemfile or Ruby's standard library. If the versions specified + # in Gemfile, only those versions would be loaded. + # + # Assuming Gemfile + # + # gem 'first_gem', '= 1.0' + # group :test do + # gem 'second_gem', '= 1.0' + # end + # + # The code using Bundler.setup works as follows: + # + # require 'third_gem' # allowed, required from global gems + # require 'first_gem' # allowed, loads the last installed version + # Bundler.setup + # require 'fourth_gem' # fails with LoadError + # require 'second_gem' # loads exactly version 1.0 + # + # +Bundler.setup+ can be called only once, all subsequent calls are no-op. + # + # If _groups_ list is provided, only gems from specified groups would + # be allowed (gems specified outside groups belong to special +:default+ group). + # + # To require all gems from Gemfile (or only some groups), see Bundler.require. + # + def setup(*groups) + # Return if all groups are already loaded + return @setup if defined?(@setup) && @setup + + definition.validate_runtime! + + SharedHelpers.print_major_deprecations! + + if groups.empty? + # Load all groups, but only once + @setup = load.setup + else + load.setup(*groups) + end + end + + # Setups Bundler environment (see Bundler.setup) if it is not already set, + # and loads all gems from groups specified. Unlike ::setup, can be called + # multiple times with different groups (if they were allowed by setup). + # + # Assuming Gemfile + # + # gem 'first_gem', '= 1.0' + # group :test do + # gem 'second_gem', '= 1.0' + # end + # + # The code will work as follows: + # + # Bundler.setup # allow all groups + # Bundler.require(:default) # requires only first_gem + # # ...later + # Bundler.require(:test) # requires second_gem + # + def require(*groups) + setup(*groups).require(*groups) + end + + def load + @load ||= Runtime.new(root, definition) + end + + def environment + SharedHelpers.major_deprecation 2, "Bundler.environment has been removed in favor of Bundler.load", :print_caller_location => true + load + end + + # Returns an instance of Bundler::Definition for given Gemfile and lockfile + # + # @param unlock [Hash, Boolean, nil] Gems that have been requested + # to be updated or true if all gems should be updated + # @return [Bundler::Definition] + def definition(unlock = nil) + @definition = nil if unlock + @definition ||= begin + configure + Definition.build(default_gemfile, default_lockfile, unlock) + end + end + + def frozen_bundle? + frozen = settings[:deployment] + frozen ||= settings[:frozen] + frozen + end + + def locked_gems + @locked_gems ||= + if defined?(@definition) && @definition + definition.locked_gems + elsif Bundler.default_lockfile.file? + lock = Bundler.read_file(Bundler.default_lockfile) + LockfileParser.new(lock) + end + end + + def most_specific_locked_platform?(platform) + return false unless defined?(@definition) && @definition + + definition.most_specific_locked_platform == platform + end + + def ruby_scope + "#{Bundler.rubygems.ruby_engine}/#{RbConfig::CONFIG["ruby_version"]}" + end + + def user_home + @user_home ||= begin + home = Bundler.rubygems.user_home + bundle_home = home ? File.join(home, ".bundle") : nil + + warning = if home.nil? + "Your home directory is not set." + elsif !File.directory?(home) + "`#{home}` is not a directory." + elsif !File.writable?(home) && (!File.directory?(bundle_home) || !File.writable?(bundle_home)) + "`#{home}` is not writable." + end + + if warning + Bundler.ui.warn "#{warning}\n" + user_home = tmp_home_path + Bundler.ui.warn "Bundler will use `#{user_home}' as your home directory temporarily.\n" + user_home + else + Pathname.new(home) + end + end + end + + def user_bundle_path(dir = "home") + env_var, fallback = case dir + when "home" + ["BUNDLE_USER_HOME", proc { Pathname.new(user_home).join(".bundle") }] + when "cache" + ["BUNDLE_USER_CACHE", proc { user_bundle_path.join("cache") }] + when "config" + ["BUNDLE_USER_CONFIG", proc { user_bundle_path.join("config") }] + when "plugin" + ["BUNDLE_USER_PLUGIN", proc { user_bundle_path.join("plugin") }] + else + raise BundlerError, "Unknown user path requested: #{dir}" + end + # `fallback` will already be a Pathname, but Pathname.new() is + # idempotent so it's OK + Pathname.new(ENV.fetch(env_var, &fallback)) + end + + def user_cache + user_bundle_path("cache") + end + + def home + bundle_path.join("bundler") + end + + def install_path + home.join("gems") + end + + def specs_path + bundle_path.join("specifications") + end + + def root + @root ||= begin + SharedHelpers.root + rescue GemfileNotFound + bundle_dir = default_bundle_dir + raise GemfileNotFound, "Could not locate Gemfile or .bundle/ directory" unless bundle_dir + Pathname.new(File.expand_path("..", bundle_dir)) + end + end + + def app_config_path + if app_config = ENV["BUNDLE_APP_CONFIG"] + app_config_pathname = Pathname.new(app_config) + + if app_config_pathname.absolute? + app_config_pathname + else + app_config_pathname.expand_path(root) + end + else + root.join(".bundle") + end + end + + def app_cache(custom_path = nil) + path = custom_path || root + Pathname.new(path).join(settings.app_cache_path) + end + + def tmp(name = Process.pid.to_s) + Kernel.send(:require, "tmpdir") + Pathname.new(Dir.mktmpdir(["bundler", name])) + end + + def rm_rf(path) + FileUtils.remove_entry_secure(path) if path && File.exist?(path) + rescue ArgumentError + message = < true + ) + + unbundled_env + end + + # @return [Hash] Environment with all bundler-related variables removed + def unbundled_env + env = original_env + + if env.key?("BUNDLER_ORIG_MANPATH") + env["MANPATH"] = env["BUNDLER_ORIG_MANPATH"] + end + + env.delete_if {|k, _| k[0, 7] == "BUNDLE_" } + + if env.key?("RUBYOPT") + rubyopt = env["RUBYOPT"].split(" ") + rubyopt.delete("-r#{File.expand_path("bundler/setup", __dir__)}") + rubyopt.delete("-rbundler/setup") + env["RUBYOPT"] = rubyopt.join(" ") + end + + if env.key?("RUBYLIB") + rubylib = env["RUBYLIB"].split(File::PATH_SEPARATOR) + rubylib.delete(__dir__) + env["RUBYLIB"] = rubylib.join(File::PATH_SEPARATOR) + end + + env + end + + # Run block with environment present before Bundler was activated + def with_original_env + with_env(original_env) { yield } + end + + # @deprecated Use `with_unbundled_env` instead + def with_clean_env + Bundler::SharedHelpers.major_deprecation( + 2, + "`Bundler.with_clean_env` has been deprecated in favor of `Bundler.with_unbundled_env`. " \ + "If you instead want the environment before bundler was originally loaded, use `Bundler.with_original_env`", + :print_caller_location => true + ) + + with_env(unbundled_env) { yield } + end + + # Run block with all bundler-related variables removed + def with_unbundled_env + with_env(unbundled_env) { yield } + end + + # Run subcommand with the environment present before Bundler was activated + def original_system(*args) + with_original_env { Kernel.system(*args) } + end + + # @deprecated Use `unbundled_system` instead + def clean_system(*args) + Bundler::SharedHelpers.major_deprecation( + 2, + "`Bundler.clean_system` has been deprecated in favor of `Bundler.unbundled_system`. " \ + "If you instead want to run the command in the environment before bundler was originally loaded, use `Bundler.original_system`", + :print_caller_location => true + ) + + with_env(unbundled_env) { Kernel.system(*args) } + end + + # Run subcommand in an environment with all bundler related variables removed + def unbundled_system(*args) + with_unbundled_env { Kernel.system(*args) } + end + + # Run a `Kernel.exec` to a subcommand with the environment present before Bundler was activated + def original_exec(*args) + with_original_env { Kernel.exec(*args) } + end + + # @deprecated Use `unbundled_exec` instead + def clean_exec(*args) + Bundler::SharedHelpers.major_deprecation( + 2, + "`Bundler.clean_exec` has been deprecated in favor of `Bundler.unbundled_exec`. " \ + "If you instead want to exec to a command in the environment before bundler was originally loaded, use `Bundler.original_exec`", + :print_caller_location => true + ) + + with_env(unbundled_env) { Kernel.exec(*args) } + end + + # Run a `Kernel.exec` to a subcommand in an environment with all bundler related variables removed + def unbundled_exec(*args) + with_env(unbundled_env) { Kernel.exec(*args) } + end + + def local_platform + return Gem::Platform::RUBY if settings[:force_ruby_platform] || Gem.platforms == [Gem::Platform::RUBY] + Gem::Platform.local + end + + def default_gemfile + SharedHelpers.default_gemfile + end + + def default_lockfile + SharedHelpers.default_lockfile + end + + def default_bundle_dir + SharedHelpers.default_bundle_dir + end + + def system_bindir + # Gem.bindir doesn't always return the location that RubyGems will install + # system binaries. If you put '-n foo' in your .gemrc, RubyGems will + # install binstubs there instead. Unfortunately, RubyGems doesn't expose + # that directory at all, so rather than parse .gemrc ourselves, we allow + # the directory to be set as well, via `bundle config set --local bindir foo`. + Bundler.settings[:system_bindir] || Bundler.rubygems.gem_bindir + end + + def preferred_gemfile_name + Bundler.settings[:init_gems_rb] ? "gems.rb" : "Gemfile" + end + + def use_system_gems? + configured_bundle_path.use_system_gems? + end + + def requires_sudo? + return @requires_sudo if defined?(@requires_sudo_ran) + + sudo_present = which "sudo" if settings.allow_sudo? + + if sudo_present + # the bundle path and subdirectories need to be writable for RubyGems + # to be able to unpack and install gems without exploding + path = bundle_path + path = path.parent until path.exist? + + # bins are written to a different location on OS X + bin_dir = Pathname.new(Bundler.system_bindir) + bin_dir = bin_dir.parent until bin_dir.exist? + + # if any directory is not writable, we need sudo + files = [path, bin_dir] | Dir[bundle_path.join("build_info/*").to_s] | Dir[bundle_path.join("*").to_s] + unwritable_files = files.reject {|f| File.writable?(f) } + sudo_needed = !unwritable_files.empty? + if sudo_needed + Bundler.ui.warn "Following files may not be writable, so sudo is needed:\n #{unwritable_files.map(&:to_s).sort.join("\n ")}" + end + end + + @requires_sudo_ran = true + @requires_sudo = settings.allow_sudo? && sudo_present && sudo_needed + end + + def mkdir_p(path, options = {}) + if requires_sudo? && !options[:no_sudo] + sudo "mkdir -p '#{path}'" unless File.exist?(path) + else + SharedHelpers.filesystem_access(path, :write) do |p| + FileUtils.mkdir_p(p) + end + end + end + + def which(executable) + if File.file?(executable) && File.executable?(executable) + executable + elsif paths = ENV["PATH"] + quote = '"'.freeze + paths.split(File::PATH_SEPARATOR).find do |path| + path = path[1..-2] if path.start_with?(quote) && path.end_with?(quote) + executable_path = File.expand_path(executable, path) + return executable_path if File.file?(executable_path) && File.executable?(executable_path) + end + end + end + + def sudo(str) + SUDO_MUTEX.synchronize do + prompt = "\n\n" + <<-PROMPT.gsub(/^ {6}/, "").strip + " " + Your user account isn't allowed to install to the system RubyGems. + You can cancel this installation and run: + + bundle config set --local path 'vendor/bundle' + bundle install + + to install the gems into ./vendor/bundle/, or you can enter your password + and install the bundled gems to RubyGems using sudo. + + Password: + PROMPT + + unless @prompted_for_sudo ||= system(%(sudo -k -p "#{prompt}" true)) + raise SudoNotPermittedError, + "Bundler requires sudo access to install at the moment. " \ + "Try installing again, granting Bundler sudo access when prompted, or installing into a different path." + end + + `sudo -p "#{prompt}" #{str}` + end + end + + def read_file(file) + SharedHelpers.filesystem_access(file, :read) do + File.open(file, "r:UTF-8", &:read) + end + end + + def load_marshal(data) + Marshal.load(data) + rescue TypeError => e + raise MarshalError, "#{e.class}: #{e.message}" + end + + def load_gemspec(file, validate = false) + @gemspec_cache ||= {} + key = File.expand_path(file) + @gemspec_cache[key] ||= load_gemspec_uncached(file, validate) + # Protect against caching side-effected gemspecs by returning a + # new instance each time. + @gemspec_cache[key].dup if @gemspec_cache[key] + end + + def load_gemspec_uncached(file, validate = false) + path = Pathname.new(file) + contents = read_file(file) + spec = if contents.start_with?("---") # YAML header + eval_yaml_gemspec(path, contents) + else + # Eval the gemspec from its parent directory, because some gemspecs + # depend on "./" relative paths. + SharedHelpers.chdir(path.dirname.to_s) do + eval_gemspec(path, contents) + end + end + return unless spec + spec.loaded_from = path.expand_path.to_s + Bundler.rubygems.validate(spec) if validate + spec + end + + def clear_gemspec_cache + @gemspec_cache = {} + end + + def git_present? + return @git_present if defined?(@git_present) + @git_present = Bundler.which("git") || Bundler.which("git.exe") + end + + def feature_flag + @feature_flag ||= FeatureFlag.new(VERSION) + end + + def reset! + reset_paths! + Plugin.reset! + reset_rubygems! + end + + def reset_settings_and_root! + @settings = nil + @root = nil + end + + def reset_paths! + @bin_path = nil + @bundler_major_version = nil + @bundle_path = nil + @configured = nil + @configured_bundle_path = nil + @definition = nil + @load = nil + @locked_gems = nil + @root = nil + @settings = nil + @setup = nil + @user_home = nil + end + + def reset_rubygems! + return unless defined?(@rubygems) && @rubygems + rubygems.undo_replacements + rubygems.reset + @rubygems = nil + end + + def configure_gem_home_and_path(path = bundle_path) + configure_gem_path + configure_gem_home(path) + Bundler.rubygems.clear_paths + end + + def self_manager + @self_manager ||= begin + require_relative "bundler/self_manager" + Bundler::SelfManager.new + end + end + + private + + def eval_yaml_gemspec(path, contents) + Kernel.require "psych" + + Gem::Specification.from_yaml(contents) + rescue ::Psych::SyntaxError, ArgumentError, Gem::EndOfYAMLException, Gem::Exception + eval_gemspec(path, contents) + end + + def eval_gemspec(path, contents) + eval(contents, TOPLEVEL_BINDING.dup, path.expand_path.to_s) + rescue ScriptError, StandardError => e + msg = "There was an error while loading `#{path.basename}`: #{e.message}" + + raise GemspecError, Dsl::DSLError.new(msg, path, e.backtrace, contents) + end + + def configure_gem_path + unless use_system_gems? + # this needs to be empty string to cause + # PathSupport.split_gem_path to only load up the + # Bundler --path setting as the GEM_PATH. + Bundler::SharedHelpers.set_env "GEM_PATH", "" + end + end + + def configure_gem_home(path) + Bundler::SharedHelpers.set_env "GEM_HOME", path.to_s + end + + def tmp_home_path + Kernel.send(:require, "tmpdir") + SharedHelpers.filesystem_access(Dir.tmpdir) do + path = Bundler.tmp + at_exit { Bundler.rm_rf(path) } + path + end + end + + # @param env [Hash] + def with_env(env) + backup = ENV.to_hash + ENV.replace(env) + yield + ensure + ENV.replace(backup) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/build_metadata.rb b/games/FNaFB2/Ruby/stdlib/bundler/build_metadata.rb new file mode 100644 index 0000000..8bffb2f --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/build_metadata.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Bundler + # Represents metadata from when the Bundler gem was built. + module BuildMetadata + # begin ivars + @release = false + # end ivars + + # A hash representation of the build metadata. + def self.to_h + { + "Built At" => built_at, + "Git SHA" => git_commit_sha, + "Released Version" => release?, + } + end + + # A string representing the date the bundler gem was built. + def self.built_at + @built_at ||= Time.now.utc.strftime("%Y-%m-%d").freeze + end + + # The SHA for the git commit the bundler gem was built from. + def self.git_commit_sha + return @git_commit_sha if instance_variable_defined? :@git_commit_sha + + # If Bundler has been installed without its .git directory and without a + # commit instance variable then we can't determine its commits SHA. + git_dir = File.expand_path("../../../.git", __dir__) + if File.directory?(git_dir) + return @git_commit_sha = Dir.chdir(git_dir) { `git rev-parse --short HEAD`.strip.freeze } + end + + @git_commit_sha ||= "unknown" + end + + # Whether this is an official release build of Bundler. + def self.release? + @release + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/capistrano.rb b/games/FNaFB2/Ruby/stdlib/bundler/capistrano.rb new file mode 100644 index 0000000..1f3712d --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/capistrano.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require_relative "shared_helpers" +Bundler::SharedHelpers.major_deprecation 2, + "The Bundler task for Capistrano. Please use https://github.com/capistrano/bundler" + +# Capistrano task for Bundler. +# +# Add "require 'bundler/capistrano'" in your Capistrano deploy.rb, and +# Bundler will be activated after each new deployment. +require_relative "deployment" +require "capistrano/version" + +if defined?(Capistrano::Version) && Gem::Version.new(Capistrano::Version).release >= Gem::Version.new("3.0") + raise "For Capistrano 3.x integration, please use https://github.com/capistrano/bundler" +end + +Capistrano::Configuration.instance(:must_exist).load do + before "deploy:finalize_update", "bundle:install" + Bundler::Deployment.define_task(self, :task, :except => { :no_release => true }) + set :rake, lambda { "#{fetch(:bundle_cmd, "bundle")} exec rake" } +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli.rb new file mode 100644 index 0000000..c5edfad --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli.rb @@ -0,0 +1,851 @@ +# frozen_string_literal: true + +require_relative "vendored_thor" + +module Bundler + class CLI < Thor + require_relative "cli/common" + + package_name "Bundler" + + AUTO_INSTALL_CMDS = %w[show binstubs outdated exec open console licenses clean].freeze + PARSEABLE_COMMANDS = %w[check config help exec platform show version].freeze + + COMMAND_ALIASES = { + "check" => "c", + "install" => "i", + "plugin" => "", + "list" => "ls", + "exec" => ["e", "ex", "exe"], + "cache" => ["package", "pack"], + "version" => ["-v", "--version"], + }.freeze + + def self.start(*) + super + ensure + Bundler::SharedHelpers.print_major_deprecations! + end + + def self.dispatch(*) + super do |i| + i.send(:print_command) + i.send(:warn_on_outdated_bundler) + end + end + + def self.all_aliases + @all_aliases ||= begin + command_aliases = {} + + COMMAND_ALIASES.each do |name, aliases| + Array(aliases).each do |one_alias| + command_aliases[one_alias] = name + end + end + + command_aliases + end + end + + def self.aliases_for(command_name) + COMMAND_ALIASES.select {|k, _| k == command_name }.invert + end + + def initialize(*args) + super + + custom_gemfile = options[:gemfile] || Bundler.settings[:gemfile] + if custom_gemfile && !custom_gemfile.empty? + Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", File.expand_path(custom_gemfile) + Bundler.reset_settings_and_root! + end + + Bundler.self_manager.restart_with_locked_bundler_if_needed + + Bundler.settings.set_command_option_if_given :retry, options[:retry] + + current_cmd = args.last[:current_command].name + auto_install if AUTO_INSTALL_CMDS.include?(current_cmd) + rescue UnknownArgumentError => e + raise InvalidOption, e.message + ensure + self.options ||= {} + unprinted_warnings = Bundler.ui.unprinted_warnings + Bundler.ui = UI::Shell.new(options) + Bundler.ui.level = "debug" if options["verbose"] + unprinted_warnings.each {|w| Bundler.ui.warn(w) } + end + + check_unknown_options!(:except => [:config, :exec]) + stop_on_unknown_option! :exec + + desc "cli_help", "Prints a summary of bundler commands", :hide => true + def cli_help + version + Bundler.ui.info "\n" + + primary_commands = ["install", "update", "cache", "exec", "config", "help"] + + list = self.class.printable_commands(true) + by_name = list.group_by {|name, _message| name.match(/^bundle (\w+)/)[1] } + utilities = by_name.keys.sort - primary_commands + primary_commands.map! {|name| (by_name[name] || raise("no primary command #{name}")).first } + utilities.map! {|name| by_name[name].first } + + shell.say "Bundler commands:\n\n" + + shell.say " Primary commands:\n" + shell.print_table(primary_commands, :indent => 4, :truncate => true) + shell.say + shell.say " Utilities:\n" + shell.print_table(utilities, :indent => 4, :truncate => true) + shell.say + self.class.send(:class_options_help, shell) + end + default_task(Bundler.feature_flag.default_cli_command) + + class_option "no-color", :type => :boolean, :desc => "Disable colorization in output" + class_option "retry", :type => :numeric, :aliases => "-r", :banner => "NUM", + :desc => "Specify the number of times you wish to attempt network commands" + class_option "verbose", :type => :boolean, :desc => "Enable verbose output mode", :aliases => "-V" + + def help(cli = nil) + case cli + when "gemfile" then command = "gemfile" + when nil then command = "bundle" + else command = "bundle-#{cli}" + end + + man_path = File.expand_path("man", __dir__) + man_pages = Hash[Dir.glob(File.join(man_path, "**", "*")).grep(/.*\.\d*\Z/).collect do |f| + [File.basename(f, ".*"), f] + end] + + if man_pages.include?(command) + man_page = man_pages[command] + if Bundler.which("man") && man_path !~ %r{^file:/.+!/META-INF/jruby.home/.+} + Kernel.exec "man #{man_page}" + else + puts File.read("#{man_path}/#{File.basename(man_page)}.ronn") + end + elsif command_path = Bundler.which("bundler-#{cli}") + Kernel.exec(command_path, "--help") + else + super + end + end + + def self.handle_no_command_error(command, has_namespace = $thor_runner) + if Bundler.feature_flag.plugins? && Bundler::Plugin.command?(command) + return Bundler::Plugin.exec_command(command, ARGV[1..-1]) + end + + return super unless command_path = Bundler.which("bundler-#{command}") + + Kernel.exec(command_path, *ARGV[1..-1]) + end + + desc "init [OPTIONS]", "Generates a Gemfile into the current working directory" + long_desc <<-D + Init generates a default Gemfile in the current working directory. When adding a + Gemfile to a gem with a gemspec, the --gemspec option will automatically add each + dependency listed in the gemspec file to the newly created Gemfile. + D + method_option "gemspec", :type => :string, :banner => "Use the specified .gemspec to create the Gemfile" + def init + require_relative "cli/init" + Init.new(options.dup).run + end + + desc "check [OPTIONS]", "Checks if the dependencies listed in Gemfile are satisfied by currently installed gems" + long_desc <<-D + Check searches the local machine for each of the gems requested in the Gemfile. If + all gems are found, Bundler prints a success message and exits with a status of 0. + If not, the first missing gem is listed and Bundler exits status 1. + D + method_option "dry-run", :type => :boolean, :default => false, :banner => + "Lock the Gemfile" + method_option "gemfile", :type => :string, :banner => + "Use the specified gemfile instead of Gemfile" + method_option "path", :type => :string, :banner => + "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME).#{" Bundler will remember this value for future installs on this machine" unless Bundler.feature_flag.forget_cli_options?}" + def check + remembered_flag_deprecation("path") + + require_relative "cli/check" + Check.new(options).run + end + + map aliases_for("check") + + desc "remove [GEM [GEM ...]]", "Removes gems from the Gemfile" + long_desc <<-D + Removes the given gems from the Gemfile while ensuring that the resulting Gemfile is still valid. If the gem is not found, Bundler prints a error message and if gem could not be removed due to any reason Bundler will display a warning. + D + method_option "install", :type => :boolean, :banner => + "Runs 'bundle install' after removing the gems from the Gemfile" + def remove(*gems) + SharedHelpers.major_deprecation(2, "The `--install` flag has been deprecated. `bundle install` is triggered by default.") if ARGV.include?("--install") + require_relative "cli/remove" + Remove.new(gems, options).run + end + + desc "install [OPTIONS]", "Install the current environment to the system" + long_desc <<-D + Install will install all of the gems in the current bundle, making them available + for use. In a freshly checked out repository, this command will give you the same + gem versions as the last person who updated the Gemfile and ran `bundle update`. + + Passing [DIR] to install (e.g. vendor) will cause the unpacked gems to be installed + into the [DIR] directory rather than into system gems. + + If the bundle has already been installed, bundler will tell you so and then exit. + D + method_option "binstubs", :type => :string, :lazy_default => "bin", :banner => + "Generate bin stubs for bundled gems to ./bin" + method_option "clean", :type => :boolean, :banner => + "Run bundle clean automatically after install" + method_option "deployment", :type => :boolean, :banner => + "Install using defaults tuned for deployment environments" + method_option "frozen", :type => :boolean, :banner => + "Do not allow the Gemfile.lock to be updated after this install" + method_option "full-index", :type => :boolean, :banner => + "Fall back to using the single-file index of all gems" + method_option "gemfile", :type => :string, :banner => + "Use the specified gemfile instead of Gemfile" + method_option "jobs", :aliases => "-j", :type => :numeric, :banner => + "Specify the number of jobs to run in parallel" + method_option "local", :type => :boolean, :banner => + "Do not attempt to fetch gems remotely and use the gem cache instead" + method_option "prefer-local", :type => :boolean, :banner => + "Only attempt to fetch gems remotely if not present locally, even if newer versions are available remotely" + method_option "no-cache", :type => :boolean, :banner => + "Don't update the existing gem cache." + method_option "redownload", :type => :boolean, :aliases => "--force", :banner => + "Force downloading every gem." + method_option "no-prune", :type => :boolean, :banner => + "Don't remove stale gems from the cache." + method_option "path", :type => :string, :banner => + "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME).#{" Bundler will remember this value for future installs on this machine" unless Bundler.feature_flag.forget_cli_options?}" + method_option "quiet", :type => :boolean, :banner => + "Only output warnings and errors." + method_option "shebang", :type => :string, :banner => + "Specify a different shebang executable name than the default (usually 'ruby')" + method_option "standalone", :type => :array, :lazy_default => [], :banner => + "Make a bundle that can work without the Bundler runtime" + method_option "system", :type => :boolean, :banner => + "Install to the system location ($BUNDLE_PATH or $GEM_HOME) even if the bundle was previously installed somewhere else for this application" + method_option "trust-policy", :alias => "P", :type => :string, :banner => + "Gem trust policy (like gem install -P). Must be one of " + + Bundler.rubygems.security_policy_keys.join("|") + method_option "without", :type => :array, :banner => + "Exclude gems that are part of the specified named group." + method_option "with", :type => :array, :banner => + "Include gems that are part of the specified named group." + def install + SharedHelpers.major_deprecation(2, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force") + + %w[clean deployment frozen no-prune path shebang system without with].each do |option| + remembered_flag_deprecation(option) + end + + remembered_negative_flag_deprecation("no-deployment") + + require_relative "cli/install" + Bundler.settings.temporary(:no_install => false) do + Install.new(options.dup).run + end + end + + map aliases_for("install") + + desc "update [OPTIONS]", "Update the current environment" + long_desc <<-D + Update will install the newest versions of the gems listed in the Gemfile. Use + update when you have changed the Gemfile, or if you want to get the newest + possible versions of the gems in the bundle. + D + method_option "full-index", :type => :boolean, :banner => + "Fall back to using the single-file index of all gems" + method_option "gemfile", :type => :string, :banner => + "Use the specified gemfile instead of Gemfile" + method_option "group", :aliases => "-g", :type => :array, :banner => + "Update a specific group" + method_option "jobs", :aliases => "-j", :type => :numeric, :banner => + "Specify the number of jobs to run in parallel" + method_option "local", :type => :boolean, :banner => + "Do not attempt to fetch gems remotely and use the gem cache instead" + method_option "quiet", :type => :boolean, :banner => + "Only output warnings and errors." + method_option "source", :type => :array, :banner => + "Update a specific source (and all gems associated with it)" + method_option "redownload", :type => :boolean, :aliases => "--force", :banner => + "Force downloading every gem." + method_option "ruby", :type => :boolean, :banner => + "Update ruby specified in Gemfile.lock" + method_option "bundler", :type => :string, :lazy_default => "> 0.a", :banner => + "Update the locked version of bundler" + method_option "patch", :type => :boolean, :banner => + "Prefer updating only to next patch version" + method_option "minor", :type => :boolean, :banner => + "Prefer updating only to next minor version" + method_option "major", :type => :boolean, :banner => + "Prefer updating to next major version (default)" + method_option "strict", :type => :boolean, :banner => + "Do not allow any gem to be updated past latest --patch | --minor | --major" + method_option "conservative", :type => :boolean, :banner => + "Use bundle install conservative update behavior and do not allow shared dependencies to be updated." + method_option "all", :type => :boolean, :banner => + "Update everything." + def update(*gems) + SharedHelpers.major_deprecation(2, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force") + require_relative "cli/update" + Bundler.settings.temporary(:no_install => false) do + Update.new(options, gems).run + end + end + + desc "show GEM [OPTIONS]", "Shows all gems that are part of the bundle, or the path to a given gem" + long_desc <<-D + Show lists the names and versions of all gems that are required by your Gemfile. + Calling show with [GEM] will list the exact location of that gem on your machine. + D + method_option "paths", :type => :boolean, + :banner => "List the paths of all gems that are required by your Gemfile." + method_option "outdated", :type => :boolean, + :banner => "Show verbose output including whether gems are outdated." + def show(gem_name = nil) + SharedHelpers.major_deprecation(2, "the `--outdated` flag to `bundle show` was undocumented and will be removed without replacement") if ARGV.include?("--outdated") + require_relative "cli/show" + Show.new(options, gem_name).run + end + + desc "list", "List all gems in the bundle" + method_option "name-only", :type => :boolean, :banner => "print only the gem names" + method_option "only-group", :type => :array, :default => [], :banner => "print gems from a given set of groups" + method_option "without-group", :type => :array, :default => [], :banner => "print all gems except from a given set of groups" + method_option "paths", :type => :boolean, :banner => "print the path to each gem in the bundle" + def list + require_relative "cli/list" + List.new(options).run + end + + map aliases_for("list") + + desc "info GEM [OPTIONS]", "Show information for the given gem" + method_option "path", :type => :boolean, :banner => "Print full path to gem" + method_option "version", :type => :boolean, :banner => "Print gem version" + def info(gem_name) + require_relative "cli/info" + Info.new(options, gem_name).run + end + + desc "binstubs GEM [OPTIONS]", "Install the binstubs of the listed gem" + long_desc <<-D + Generate binstubs for executables in [GEM]. Binstubs are put into bin, + or the --binstubs directory if one has been set. Calling binstubs with [GEM [GEM]] + will create binstubs for all given gems. + D + method_option "force", :type => :boolean, :default => false, :banner => + "Overwrite existing binstubs if they exist" + method_option "path", :type => :string, :lazy_default => "bin", :banner => + "Binstub destination directory (default bin)" + method_option "shebang", :type => :string, :banner => + "Specify a different shebang executable name than the default (usually 'ruby')" + method_option "standalone", :type => :boolean, :banner => + "Make binstubs that can work without the Bundler runtime" + method_option "all", :type => :boolean, :banner => + "Install binstubs for all gems" + method_option "all-platforms", :type => :boolean, :default => false, :banner => + "Install binstubs for all platforms" + def binstubs(*gems) + require_relative "cli/binstubs" + Binstubs.new(options, gems).run + end + + desc "add GEM VERSION", "Add gem to Gemfile and run bundle install" + long_desc <<-D + Adds the specified gem to Gemfile (if valid) and run 'bundle install' in one step. + D + method_option "version", :aliases => "-v", :type => :string + method_option "group", :aliases => "-g", :type => :string + method_option "source", :aliases => "-s", :type => :string + method_option "require", :aliases => "-r", :type => :string, :banner => "Adds require path to gem. Provide false, or a path as a string." + method_option "path", :type => :string + method_option "git", :type => :string + method_option "github", :type => :string + method_option "branch", :type => :string + method_option "ref", :type => :string + method_option "skip-install", :type => :boolean, :banner => + "Adds gem to the Gemfile but does not install it" + method_option "optimistic", :type => :boolean, :banner => "Adds optimistic declaration of version to gem" + method_option "strict", :type => :boolean, :banner => "Adds strict declaration of version to gem" + def add(*gems) + require_relative "cli/add" + Add.new(options.dup, gems).run + end + + desc "outdated GEM [OPTIONS]", "List installed gems with newer versions available" + long_desc <<-D + Outdated lists the names and versions of gems that have a newer version available + in the given source. Calling outdated with [GEM [GEM]] will only check for newer + versions of the given gems. Prerelease gems are ignored by default. If your gems + are up to date, Bundler will exit with a status of 0. Otherwise, it will exit 1. + + For more information on patch level options (--major, --minor, --patch, + --strict) see documentation on the same options on the update command. + D + method_option "group", :type => :string, :banner => "List gems from a specific group" + method_option "groups", :type => :boolean, :banner => "List gems organized by groups" + method_option "local", :type => :boolean, :banner => + "Do not attempt to fetch gems remotely and use the gem cache instead" + method_option "pre", :type => :boolean, :banner => "Check for newer pre-release gems" + method_option "source", :type => :array, :banner => "Check against a specific source" + method_option "filter-strict", :type => :boolean, :aliases => "--strict", :banner => + "Only list newer versions allowed by your Gemfile requirements" + method_option "update-strict", :type => :boolean, :banner => + "Strict conservative resolution, do not allow any gem to be updated past latest --patch | --minor | --major" + method_option "minor", :type => :boolean, :banner => "Prefer updating only to next minor version" + method_option "major", :type => :boolean, :banner => "Prefer updating to next major version (default)" + method_option "patch", :type => :boolean, :banner => "Prefer updating only to next patch version" + method_option "filter-major", :type => :boolean, :banner => "Only list major newer versions" + method_option "filter-minor", :type => :boolean, :banner => "Only list minor newer versions" + method_option "filter-patch", :type => :boolean, :banner => "Only list patch newer versions" + method_option "parseable", :aliases => "--porcelain", :type => :boolean, :banner => + "Use minimal formatting for more parseable output" + method_option "only-explicit", :type => :boolean, :banner => + "Only list gems specified in your Gemfile, not their dependencies" + def outdated(*gems) + require_relative "cli/outdated" + Outdated.new(options, gems).run + end + + desc "fund [OPTIONS]", "Lists information about gems seeking funding assistance" + method_option "group", :aliases => "-g", :type => :array, :banner => + "Fetch funding information for a specific group" + def fund + require_relative "cli/fund" + Fund.new(options).run + end + + desc "cache [OPTIONS]", "Locks and then caches all of the gems into vendor/cache" + method_option "all", :type => :boolean, + :default => Bundler.feature_flag.cache_all?, + :banner => "Include all sources (including path and git)." + method_option "all-platforms", :type => :boolean, :banner => "Include gems for all platforms present in the lockfile, not only the current one" + method_option "cache-path", :type => :string, :banner => + "Specify a different cache path than the default (vendor/cache)." + method_option "gemfile", :type => :string, :banner => "Use the specified gemfile instead of Gemfile" + method_option "no-install", :type => :boolean, :banner => "Don't install the gems, only update the cache." + method_option "no-prune", :type => :boolean, :banner => "Don't remove stale gems from the cache." + method_option "path", :type => :string, :banner => + "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME).#{" Bundler will remember this value for future installs on this machine" unless Bundler.feature_flag.forget_cli_options?}" + method_option "quiet", :type => :boolean, :banner => "Only output warnings and errors." + method_option "frozen", :type => :boolean, :banner => + "Do not allow the Gemfile.lock to be updated after this bundle cache operation's install" + long_desc <<-D + The cache command will copy the .gem files for every gem in the bundle into the + directory ./vendor/cache. If you then check that directory into your source + control repository, others who check out your source will be able to install the + bundle without having to download any additional gems. + D + def cache + SharedHelpers.major_deprecation 2, + "The `--all` flag is deprecated because it relies on being " \ + "remembered across bundler invocations, which bundler will no longer " \ + "do in future versions. Instead please use `bundle config set cache_all true`, " \ + "and stop using this flag" if ARGV.include?("--all") + + SharedHelpers.major_deprecation 2, + "The `--path` flag is deprecated because its semantics are unclear. " \ + "Use `bundle config cache_path` to configure the path of your cache of gems, " \ + "and `bundle config path` to configure the path where your gems are installed, " \ + "and stop using this flag" if ARGV.include?("--path") + + require_relative "cli/cache" + Cache.new(options).run + end + + map aliases_for("cache") + + desc "exec [OPTIONS]", "Run the command in context of the bundle" + method_option :keep_file_descriptors, :type => :boolean, :default => true + method_option :gemfile, :type => :string, :required => false + long_desc <<-D + Exec runs a command, providing it access to the gems in the bundle. While using + bundle exec you can require and call the bundled gems as if they were installed + into the system wide RubyGems repository. + D + def exec(*args) + if ARGV.include?("--no-keep-file-descriptors") + SharedHelpers.major_deprecation(2, "The `--no-keep-file-descriptors` has been deprecated. `bundle exec` no longer mess with your file descriptors. Close them in the exec'd script if you need to") + end + + require_relative "cli/exec" + Exec.new(options, args).run + end + + map aliases_for("exec") + + desc "config NAME [VALUE]", "Retrieve or set a configuration value" + long_desc <<-D + Retrieves or sets a configuration value. If only one parameter is provided, retrieve the value. If two parameters are provided, replace the + existing value with the newly provided one. + + By default, setting a configuration value sets it for all projects + on the machine. + + If a global setting is superseded by local configuration, this command + will show the current value, as well as any superseded values and + where they were specified. + D + require_relative "cli/config" + subcommand "config", Config + + desc "open GEM", "Opens the source directory of the given bundled gem" + def open(name) + require_relative "cli/open" + Open.new(options, name).run + end + + unless Bundler.feature_flag.bundler_3_mode? + desc "console [GROUP]", "Opens an IRB session with the bundle pre-loaded" + def console(group = nil) + require_relative "cli/console" + Console.new(options, group).run + end + end + + desc "version", "Prints Bundler version information" + def version + cli_help = current_command.name == "cli_help" + if cli_help || ARGV.include?("version") + build_info = " (#{BuildMetadata.built_at} commit #{BuildMetadata.git_commit_sha})" + end + + if !cli_help && Bundler.feature_flag.print_only_version_number? + Bundler.ui.info "#{Bundler::VERSION}#{build_info}" + else + Bundler.ui.info "Bundler version #{Bundler::VERSION}#{build_info}" + end + end + + map aliases_for("version") + + desc "licenses", "Prints the license of all gems in the bundle" + def licenses + Bundler.load.specs.sort_by {|s| s.license.to_s }.reverse_each do |s| + gem_name = s.name + license = s.license || s.licenses + + if license.empty? + Bundler.ui.warn "#{gem_name}: Unknown" + else + Bundler.ui.info "#{gem_name}: #{license}" + end + end + end + + unless Bundler.feature_flag.bundler_3_mode? + desc "viz [OPTIONS]", "Generates a visual dependency graph", :hide => true + long_desc <<-D + Viz generates a PNG file of the current Gemfile as a dependency graph. + Viz requires the ruby-graphviz gem (and its dependencies). + The associated gems must also be installed via 'bundle install'. + D + method_option :file, :type => :string, :default => "gem_graph", :aliases => "-f", :desc => "The name to use for the generated file. see format option" + method_option :format, :type => :string, :default => "png", :aliases => "-F", :desc => "This is output format option. Supported format is png, jpg, svg, dot ..." + method_option :requirements, :type => :boolean, :default => false, :aliases => "-R", :desc => "Set to show the version of each required dependency." + method_option :version, :type => :boolean, :default => false, :aliases => "-v", :desc => "Set to show each gem version." + method_option :without, :type => :array, :default => [], :aliases => "-W", :banner => "GROUP[ GROUP...]", :desc => "Exclude gems that are part of the specified named group." + def viz + SharedHelpers.major_deprecation 2, "The `viz` command has been renamed to `graph` and moved to a plugin. See https://github.com/rubygems/bundler-graph" + require_relative "cli/viz" + Viz.new(options.dup).run + end + end + + old_gem = instance_method(:gem) + + desc "gem NAME [OPTIONS]", "Creates a skeleton for creating a rubygem" + method_option :exe, :type => :boolean, :default => false, :aliases => ["--bin", "-b"], :desc => "Generate a binary executable for your library." + method_option :coc, :type => :boolean, :desc => "Generate a code of conduct file. Set a default with `bundle config set --global gem.coc true`." + method_option :edit, :type => :string, :aliases => "-e", :required => false, :banner => "EDITOR", + :lazy_default => [ENV["BUNDLER_EDITOR"], ENV["VISUAL"], ENV["EDITOR"]].find {|e| !e.nil? && !e.empty? }, + :desc => "Open generated gemspec in the specified editor (defaults to $EDITOR or $BUNDLER_EDITOR)" + method_option :ext, :type => :boolean, :default => false, :desc => "Generate the boilerplate for C extension code" + method_option :git, :type => :boolean, :default => true, :desc => "Initialize a git repo inside your library." + method_option :mit, :type => :boolean, :desc => "Generate an MIT license file. Set a default with `bundle config set --global gem.mit true`." + method_option :rubocop, :type => :boolean, :desc => "Add rubocop to the generated Rakefile and gemspec. Set a default with `bundle config set --global gem.rubocop true`." + method_option :changelog, :type => :boolean, :desc => "Generate changelog file. Set a default with `bundle config set --global gem.changelog true`." + method_option :test, :type => :string, :lazy_default => Bundler.settings["gem.test"] || "", :aliases => "-t", :banner => "Use the specified test framework for your library", + :desc => "Generate a test directory for your library, either rspec, minitest or test-unit. Set a default with `bundle config set --global gem.test (rspec|minitest|test-unit)`." + method_option :ci, :type => :string, :lazy_default => Bundler.settings["gem.ci"] || "", + :desc => "Generate CI configuration, either GitHub Actions, Travis CI, GitLab CI or CircleCI. Set a default with `bundle config set --global gem.ci (github|travis|gitlab|circle)`" + method_option :linter, :type => :string, :lazy_default => Bundler.settings["gem.linter"] || "", + :desc => "Add a linter and code formatter, either RuboCop or Standard. Set a default with `bundle config set --global gem.linter (rubocop|standard)`" + method_option :github_username, :type => :string, :default => Bundler.settings["gem.github_username"], :banner => "Set your username on GitHub", :desc => "Fill in GitHub username on README so that you don't have to do it manually. Set a default with `bundle config set --global gem.github_username `." + + def gem(name) + end + + commands["gem"].tap do |gem_command| + def gem_command.run(instance, args = []) + arity = 1 # name + + require_relative "cli/gem" + cmd_args = args + [instance] + cmd_args.unshift(instance.options) + + cmd = begin + Gem.new(*cmd_args) + rescue ArgumentError => e + instance.class.handle_argument_error(self, e, args, arity) + end + + cmd.run + end + end + + undef_method(:gem) + define_method(:gem, old_gem) + private :gem + + def self.source_root + File.expand_path("templates", __dir__) + end + + desc "clean [OPTIONS]", "Cleans up unused gems in your bundler directory", :hide => true + method_option "dry-run", :type => :boolean, :default => false, :banner => + "Only print out changes, do not clean gems" + method_option "force", :type => :boolean, :default => false, :banner => + "Forces cleaning up unused gems even if Bundler is configured to use globally installed gems. As a consequence, removes all system gems except for the ones in the current application." + def clean + require_relative "cli/clean" + Clean.new(options.dup).run + end + + desc "platform [OPTIONS]", "Displays platform compatibility information" + method_option "ruby", :type => :boolean, :default => false, :banner => + "only display ruby related platform information" + def platform + require_relative "cli/platform" + Platform.new(options).run + end + + desc "inject GEM VERSION", "Add the named gem, with version requirements, to the resolved Gemfile", :hide => true + method_option "source", :type => :string, :banner => + "Install gem from the given source" + method_option "group", :type => :string, :banner => + "Install gem into a bundler group" + def inject(name, version) + SharedHelpers.major_deprecation 2, "The `inject` command has been replaced by the `add` command" + require_relative "cli/inject" + Inject.new(options.dup, name, version).run + end + + desc "lock", "Creates a lockfile without installing" + method_option "update", :type => :array, :lazy_default => true, :banner => + "ignore the existing lockfile, update all gems by default, or update list of given gems" + method_option "local", :type => :boolean, :default => false, :banner => + "do not attempt to fetch remote gemspecs and use the local gem cache only" + method_option "print", :type => :boolean, :default => false, :banner => + "print the lockfile to STDOUT instead of writing to the file system" + method_option "gemfile", :type => :string, :banner => + "Use the specified gemfile instead of Gemfile" + method_option "lockfile", :type => :string, :default => nil, :banner => + "the path the lockfile should be written to" + method_option "full-index", :type => :boolean, :default => false, :banner => + "Fall back to using the single-file index of all gems" + method_option "add-platform", :type => :array, :default => [], :banner => + "Add a new platform to the lockfile" + method_option "remove-platform", :type => :array, :default => [], :banner => + "Remove a platform from the lockfile" + method_option "patch", :type => :boolean, :banner => + "If updating, prefer updating only to next patch version" + method_option "minor", :type => :boolean, :banner => + "If updating, prefer updating only to next minor version" + method_option "major", :type => :boolean, :banner => + "If updating, prefer updating to next major version (default)" + method_option "strict", :type => :boolean, :banner => + "If updating, do not allow any gem to be updated past latest --patch | --minor | --major" + method_option "conservative", :type => :boolean, :banner => + "If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated" + def lock + require_relative "cli/lock" + Lock.new(options).run + end + + desc "env", "Print information about the environment Bundler is running under" + def env + Env.write($stdout) + end + + desc "doctor [OPTIONS]", "Checks the bundle for common problems" + long_desc <<-D + Doctor scans the OS dependencies of each of the gems requested in the Gemfile. If + missing dependencies are detected, Bundler prints them and exits status 1. + Otherwise, Bundler prints a success message and exits with a status of 0. + D + method_option "gemfile", :type => :string, :banner => + "Use the specified gemfile instead of Gemfile" + method_option "quiet", :type => :boolean, :banner => + "Only output warnings and errors." + def doctor + require_relative "cli/doctor" + Doctor.new(options).run + end + + desc "issue", "Learn how to report an issue in Bundler" + def issue + require_relative "cli/issue" + Issue.new.run + end + + desc "pristine [GEMS...]", "Restores installed gems to pristine condition" + long_desc <<-D + Restores installed gems to pristine condition from files located in the + gem cache. Gems installed from a git repository will be issued `git + checkout --force`. + D + def pristine(*gems) + require_relative "cli/pristine" + Pristine.new(gems).run + end + + if Bundler.feature_flag.plugins? + require_relative "cli/plugin" + desc "plugin", "Manage the bundler plugins" + subcommand "plugin", Plugin + end + + # Reformat the arguments passed to bundle that include a --help flag + # into the corresponding `bundle help #{command}` call + def self.reformatted_help_args(args) + bundler_commands = (COMMAND_ALIASES.keys + COMMAND_ALIASES.values).flatten + + help_flags = %w[--help -h] + exec_commands = ["exec"] + COMMAND_ALIASES["exec"] + + help_used = args.index {|a| help_flags.include? a } + exec_used = args.index {|a| exec_commands.include? a } + + command = args.find {|a| bundler_commands.include? a } + command = all_aliases[command] if all_aliases[command] + + if exec_used && help_used + if exec_used + help_used == 1 + %w[help exec] + else + args + end + elsif help_used + args = args.dup + args.delete_at(help_used) + ["help", command || args].flatten.compact + else + args + end + end + + private + + # Automatically invoke `bundle install` and resume if + # Bundler.settings[:auto_install] exists. This is set through config cmd + # `bundle config set --global auto_install 1`. + # + # Note that this method `nil`s out the global Definition object, so it + # should be called first, before you instantiate anything like an + # `Installer` that'll keep a reference to the old one instead. + def auto_install + return unless Bundler.settings[:auto_install] + + begin + Bundler.definition.specs + rescue GemNotFound + Bundler.ui.info "Automatically installing missing gems." + Bundler.reset! + invoke :install, [] + Bundler.reset! + end + end + + def current_command + _, _, config = @_initializer + config[:current_command] + end + + def print_command + return unless Bundler.ui.debug? + cmd = current_command + command_name = cmd.name + return if PARSEABLE_COMMANDS.include?(command_name) + command = ["bundle", command_name] + args + options_to_print = options.dup + options_to_print.delete_if do |k, v| + next unless o = cmd.options[k] + o.default == v + end + command << Thor::Options.to_switches(options_to_print.sort_by(&:first)).strip + command.reject!(&:empty?) + Bundler.ui.info "Running `#{command * " "}` with bundler #{Bundler::VERSION}" + end + + def warn_on_outdated_bundler + return if Bundler.settings[:disable_version_check] + + command_name = current_command.name + return if PARSEABLE_COMMANDS.include?(command_name) + + return unless SharedHelpers.md5_available? + + latest = Fetcher::CompactIndex. + new(nil, Source::Rubygems::Remote.new(Bundler::URI("https://rubygems.org")), nil). + send(:compact_index_client). + instance_variable_get(:@cache). + dependencies("bundler"). + map {|d| Gem::Version.new(d.first) }. + max + return unless latest + + current = Gem::Version.new(VERSION) + return if current >= latest + + Bundler.ui.warn \ + "The latest bundler is #{latest}, but you are currently running #{current}.\n" \ + "To update to the most recent version, run `bundle update --bundler`" + rescue RuntimeError + nil + end + + def remembered_negative_flag_deprecation(name) + positive_name = name.gsub(/\Ano-/, "") + option = current_command.options[positive_name] + flag_name = "--no-" + option.switch_name.gsub(/\A--/, "") + + flag_deprecation(positive_name, flag_name, option) + end + + def remembered_flag_deprecation(name) + option = current_command.options[name] + flag_name = option.switch_name + + flag_deprecation(name, flag_name, option) + end + + def flag_deprecation(name, flag_name, option) + name_index = ARGV.find {|arg| flag_name == arg.split("=")[0] } + return unless name_index + + value = options[name] + value = value.join(" ").to_s if option.type == :array + + Bundler::SharedHelpers.major_deprecation 2, + "The `#{flag_name}` flag is deprecated because it relies on being " \ + "remembered across bundler invocations, which bundler will no longer " \ + "do in future versions. Instead please use `bundle config set --local #{name.tr("-", "_")} " \ + "'#{value}'`, and stop using this flag" + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/add.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/add.rb new file mode 100644 index 0000000..5bcf30d --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/add.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Add + attr_reader :gems, :options, :version + + def initialize(options, gems) + @gems = gems + @options = options + @options[:group] = options[:group].split(",").map(&:strip) unless options[:group].nil? + @version = options[:version].split(",").map(&:strip) unless options[:version].nil? + end + + def run + validate_options! + inject_dependencies + perform_bundle_install unless options["skip-install"] + end + + private + + def perform_bundle_install + Installer.install(Bundler.root, Bundler.definition) + Bundler.load.cache if Bundler.app_cache.exist? + end + + def inject_dependencies + dependencies = gems.map {|g| Bundler::Dependency.new(g, version, options) } + + Injector.inject(dependencies, + :conservative_versioning => options[:version].nil?, # Perform conservative versioning only when version is not specified + :optimistic => options[:optimistic], + :strict => options[:strict]) + end + + def validate_options! + raise InvalidOption, "You can not specify `--strict` and `--optimistic` at the same time." if options[:strict] && options[:optimistic] + + # raise error when no gems are specified + raise InvalidOption, "Please specify gems to add." if gems.empty? + + version.to_a.each do |v| + raise InvalidOption, "Invalid gem requirement pattern '#{v}'" unless Gem::Requirement::PATTERN =~ v.to_s + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/binstubs.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/binstubs.rb new file mode 100644 index 0000000..639c01f --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/binstubs.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Binstubs + attr_reader :options, :gems + def initialize(options, gems) + @options = options + @gems = gems + end + + def run + Bundler.definition.validate_runtime! + path_option = options["path"] + path_option = nil if path_option && path_option.empty? + Bundler.settings.set_command_option :bin, path_option if options["path"] + Bundler.settings.set_command_option_if_given :shebang, options["shebang"] + installer = Installer.new(Bundler.root, Bundler.definition) + + installer_opts = { + :force => options[:force], + :binstubs_cmd => true, + :all_platforms => options["all-platforms"], + } + + if options[:all] + raise InvalidOption, "Cannot specify --all with specific gems" unless gems.empty? + @gems = Bundler.definition.specs.map(&:name) + installer_opts.delete(:binstubs_cmd) + elsif gems.empty? + Bundler.ui.error "`bundle binstubs` needs at least one gem to run." + exit 1 + end + + gems.each do |gem_name| + spec = Bundler.definition.specs.find {|s| s.name == gem_name } + unless spec + raise GemNotFound, Bundler::CLI::Common.gem_not_found_message( + gem_name, Bundler.definition.specs + ) + end + + if options[:standalone] + next Bundler.ui.warn("Sorry, Bundler can only be run via RubyGems.") if gem_name == "bundler" + Bundler.settings.temporary(:path => (Bundler.settings[:path] || Bundler.root)) do + installer.generate_standalone_bundler_executable_stubs(spec, installer_opts) + end + else + installer.generate_bundler_executable_stubs(spec, installer_opts) + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/cache.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/cache.rb new file mode 100644 index 0000000..c8698ed --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/cache.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Cache + attr_reader :options + + def initialize(options) + @options = options + end + + def run + Bundler.ui.level = "warn" if options[:quiet] + Bundler.settings.set_command_option_if_given :path, options[:path] + Bundler.settings.set_command_option_if_given :cache_path, options["cache-path"] + + setup_cache_all + install + + # TODO: move cache contents here now that all bundles are locked + custom_path = Bundler.settings[:path] if options[:path] + + Bundler.settings.temporary(:cache_all_platforms => options["all-platforms"]) do + Bundler.load.cache(custom_path) + end + end + + private + + def install + require_relative "install" + options = self.options.dup + options["local"] = false if Bundler.settings[:cache_all_platforms] + options["no-cache"] = true + Bundler::CLI::Install.new(options).run + end + + def setup_cache_all + all = options.fetch(:all, Bundler.feature_flag.cache_all? || nil) + + Bundler.settings.set_command_option_if_given :cache_all, all + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/check.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/check.rb new file mode 100644 index 0000000..65c5133 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/check.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Check + attr_reader :options + + def initialize(options) + @options = options + end + + def run + Bundler.settings.set_command_option_if_given :path, options[:path] + + definition = Bundler.definition + definition.validate_runtime! + + begin + definition.resolve_only_locally! + not_installed = definition.missing_specs + rescue GemNotFound, VersionConflict + Bundler.ui.error "Bundler can't satisfy your Gemfile's dependencies." + Bundler.ui.warn "Install missing gems with `bundle install`." + exit 1 + end + + if not_installed.any? + Bundler.ui.error "The following gems are missing" + not_installed.each {|s| Bundler.ui.error " * #{s.name} (#{s.version})" } + Bundler.ui.warn "Install missing gems with `bundle install`" + exit 1 + elsif !Bundler.default_lockfile.file? && Bundler.frozen_bundle? + Bundler.ui.error "This bundle has been frozen, but there is no #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} present" + exit 1 + else + Bundler.load.lock(:preserve_unknown_sections => true) unless options[:"dry-run"] + Bundler.ui.info "The Gemfile's dependencies are satisfied" + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/clean.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/clean.rb new file mode 100644 index 0000000..c6b0968 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/clean.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Clean + attr_reader :options + + def initialize(options) + @options = options + end + + def run + require_path_or_force unless options[:"dry-run"] + Bundler.load.clean(options[:"dry-run"]) + end + + protected + + def require_path_or_force + return unless Bundler.use_system_gems? && !options[:force] + raise InvalidOption, "Cleaning all the gems on your system is dangerous! " \ + "If you're sure you want to remove every system gem not in this " \ + "bundle, run `bundle clean --force`." + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/common.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/common.rb new file mode 100644 index 0000000..0d83a1c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/common.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +module Bundler + module CLI::Common + def self.output_post_install_messages(messages) + return if Bundler.settings["ignore_messages"] + messages.to_a.each do |name, msg| + print_post_install_message(name, msg) unless Bundler.settings["ignore_messages.#{name}"] + end + end + + def self.print_post_install_message(name, msg) + Bundler.ui.confirm "Post-install message from #{name}:" + Bundler.ui.info msg + end + + def self.output_fund_metadata_summary + return if Bundler.settings["ignore_funding_requests"] + definition = Bundler.definition + current_dependencies = definition.requested_dependencies + current_specs = definition.specs + + count = current_dependencies.count {|dep| current_specs[dep.name].first.metadata.key?("funding_uri") } + + return if count.zero? + + intro = count > 1 ? "#{count} installed gems you directly depend on are" : "#{count} installed gem you directly depend on is" + message = "#{intro} looking for funding.\n Run `bundle fund` for details" + Bundler.ui.info message + end + + def self.output_without_groups_message(command) + return if Bundler.settings[:without].empty? + Bundler.ui.confirm without_groups_message(command) + end + + def self.without_groups_message(command) + command_in_past_tense = command == :install ? "installed" : "updated" + groups = Bundler.settings[:without] + "Gems in the #{verbalize_groups(groups)} were not #{command_in_past_tense}." + end + + def self.verbalize_groups(groups) + groups.map! {|g| "'#{g}'" } + group_list = [groups[0...-1].join(", "), groups[-1..-1]]. + reject {|s| s.to_s.empty? }.join(" and ") + group_str = groups.size == 1 ? "group" : "groups" + "#{group_str} #{group_list}" + end + + def self.select_spec(name, regex_match = nil) + specs = [] + regexp = Regexp.new(name) if regex_match + + Bundler.definition.specs.each do |spec| + return spec if spec.name == name + specs << spec if regexp && spec.name =~ regexp + end + + case specs.count + when 0 + dep_in_other_group = Bundler.definition.current_dependencies.find {|dep|dep.name == name } + + if dep_in_other_group + raise GemNotFound, "Could not find gem '#{name}', because it's in the #{verbalize_groups(dep_in_other_group.groups)}, configured to be ignored." + else + raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies) + end + when 1 + specs.first + else + ask_for_spec_from(specs) + end + rescue RegexpError + raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies) + end + + def self.ask_for_spec_from(specs) + specs.each_with_index do |spec, index| + Bundler.ui.info "#{index.succ} : #{spec.name}", true + end + Bundler.ui.info "0 : - exit -", true + + num = Bundler.ui.ask("> ").to_i + num > 0 ? specs[num - 1] : nil + end + + def self.gem_not_found_message(missing_gem_name, alternatives) + require_relative "../similarity_detector" + message = "Could not find gem '#{missing_gem_name}'." + alternate_names = alternatives.map {|a| a.respond_to?(:name) ? a.name : a } + suggestions = SimilarityDetector.new(alternate_names).similar_word_list(missing_gem_name) + message += "\nDid you mean #{suggestions}?" if suggestions + message + end + + def self.ensure_all_gems_in_lockfile!(names, locked_gems = Bundler.locked_gems) + return unless locked_gems + + locked_names = locked_gems.specs.map(&:name).uniq + names.-(locked_names).each do |g| + raise GemNotFound, gem_not_found_message(g, locked_names) + end + end + + def self.configure_gem_version_promoter(definition, options) + patch_level = patch_level_options(options) + patch_level << :patch if patch_level.empty? && Bundler.settings[:prefer_patch] + raise InvalidOption, "Provide only one of the following options: #{patch_level.join(", ")}" unless patch_level.length <= 1 + + definition.gem_version_promoter.tap do |gvp| + gvp.level = patch_level.first || :major + gvp.strict = options[:strict] || options["filter-strict"] + end + end + + def self.patch_level_options(options) + [:major, :minor, :patch].select {|v| options.keys.include?(v.to_s) } + end + + def self.clean_after_install? + clean = Bundler.settings[:clean] + return clean unless clean.nil? + clean ||= Bundler.feature_flag.auto_clean_without_path? && Bundler.settings[:path].nil? + clean &&= !Bundler.use_system_gems? + clean + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/config.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/config.rb new file mode 100644 index 0000000..e1222c7 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/config.rb @@ -0,0 +1,203 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Config < Thor + class_option :parseable, :type => :boolean, :banner => "Use minimal formatting for more parseable output" + + def self.scope_options + method_option :global, :type => :boolean, :banner => "Only change the global config" + method_option :local, :type => :boolean, :banner => "Only change the local config" + end + private_class_method :scope_options + + desc "base NAME [VALUE]", "The Bundler 1 config interface", :hide => true + scope_options + method_option :delete, :type => :boolean, :banner => "delete" + def base(name = nil, *value) + new_args = + if ARGV.size == 1 + ["config", "list"] + elsif ARGV.include?("--delete") + ARGV.map {|arg| arg == "--delete" ? "unset" : arg } + elsif ARGV.include?("--global") || ARGV.include?("--local") || ARGV.size == 3 + ["config", "set", *ARGV[1..-1]] + else + ["config", "get", ARGV[1]] + end + + SharedHelpers.major_deprecation 3, + "Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle #{new_args.join(" ")}` instead." + + Base.new(options, name, value, self).run + end + + desc "list", "List out all configured settings" + def list + Base.new(options, nil, nil, self).run + end + + desc "get NAME", "Returns the value for the given key" + def get(name) + Base.new(options, name, nil, self).run + end + + desc "set NAME VALUE", "Sets the given value for the given key" + scope_options + def set(name, value, *value_) + Base.new(options, name, value_.unshift(value), self).run + end + + desc "unset NAME", "Unsets the value for the given key" + scope_options + def unset(name) + options[:delete] = true + Base.new(options, name, nil, self).run + end + + default_task :base + + class Base + attr_reader :name, :value, :options, :scope, :thor + + def initialize(options, name, value, thor) + @options = options + @name = name + value = Array(value) + @value = value.empty? ? nil : value.join(" ") + @thor = thor + validate_scope! + end + + def run + unless name + warn_unused_scope "Ignoring --#{scope}" + confirm_all + return + end + + if options[:delete] + if !explicit_scope? || scope != "global" + Bundler.settings.set_local(name, nil) + end + if !explicit_scope? || scope != "local" + Bundler.settings.set_global(name, nil) + end + return + end + + if value.nil? + warn_unused_scope "Ignoring --#{scope} since no value to set was given" + + if options[:parseable] + if value = Bundler.settings[name] + Bundler.ui.info("#{name}=#{value}") + end + return + end + + confirm(name) + return + end + + Bundler.ui.info(message) if message + Bundler.settings.send("set_#{scope}", name, new_value) + end + + def confirm_all + if @options[:parseable] + thor.with_padding do + Bundler.settings.all.each do |setting| + val = Bundler.settings[setting] + Bundler.ui.info "#{setting}=#{val}" + end + end + else + Bundler.ui.confirm "Settings are listed in order of priority. The top value will be used.\n" + Bundler.settings.all.each do |setting| + Bundler.ui.confirm setting + show_pretty_values_for(setting) + Bundler.ui.confirm "" + end + end + end + + def confirm(name) + Bundler.ui.confirm "Settings for `#{name}` in order of priority. The top value will be used" + show_pretty_values_for(name) + end + + def new_value + pathname = Pathname.new(value) + if name.start_with?("local.") && pathname.directory? + pathname.expand_path.to_s + else + value + end + end + + def message + locations = Bundler.settings.locations(name) + if @options[:parseable] + "#{name}=#{new_value}" if new_value + elsif scope == "global" + if !locations[:local].nil? + "Your application has set #{name} to #{locations[:local].inspect}. " \ + "This will override the global value you are currently setting" + elsif locations[:env] + "You have a bundler environment variable for #{name} set to " \ + "#{locations[:env].inspect}. This will take precedence over the global value you are setting" + elsif !locations[:global].nil? && locations[:global] != value + "You are replacing the current global value of #{name}, which is currently " \ + "#{locations[:global].inspect}" + end + elsif scope == "local" && !locations[:local].nil? && locations[:local] != value + "You are replacing the current local value of #{name}, which is currently " \ + "#{locations[:local].inspect}" + end + end + + def show_pretty_values_for(setting) + thor.with_padding do + Bundler.settings.pretty_values_for(setting).each do |line| + Bundler.ui.info line + end + end + end + + def explicit_scope? + @explicit_scope + end + + def warn_unused_scope(msg) + return unless explicit_scope? + return if options[:parseable] + + Bundler.ui.warn(msg) + end + + def validate_scope! + @explicit_scope = true + scopes = %w[global local].select {|s| options[s] } + case scopes.size + when 0 + @scope = inside_app? ? "local" : "global" + @explicit_scope = false + when 1 + @scope = scopes.first + else + raise InvalidOption, + "The options #{scopes.join " and "} were specified. Please only use one of the switches at a time." + end + end + + private + + def inside_app? + Bundler.root + true + rescue GemfileNotFound + false + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/console.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/console.rb new file mode 100644 index 0000000..97b8dc0 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/console.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Console + attr_reader :options, :group + def initialize(options, group) + @options = options + @group = group + end + + def run + Bundler::SharedHelpers.major_deprecation 2, "bundle console will be replaced " \ + "by `bin/console` generated by `bundle gem `" + + group ? Bundler.require(:default, *group.split(" ").map!(&:to_sym)) : Bundler.require + ARGV.clear + + console = get_console(Bundler.settings[:console] || "irb") + console.start + end + + def get_console(name) + require name + get_constant(name) + rescue LoadError + Bundler.ui.error "Couldn't load console #{name}, falling back to irb" + require "irb" + get_constant("irb") + end + + def get_constant(name) + const_name = { + "pry" => :Pry, + "ripl" => :Ripl, + "irb" => :IRB, + }[name] + Object.const_get(const_name) + rescue NameError + Bundler.ui.error "Could not find constant #{const_name}" + exit 1 + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/doctor.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/doctor.rb new file mode 100644 index 0000000..74444ad --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/doctor.rb @@ -0,0 +1,159 @@ +# frozen_string_literal: true + +require "rbconfig" +require "shellwords" +require "fiddle" + +module Bundler + class CLI::Doctor + DARWIN_REGEX = /\s+(.+) \(compatibility /.freeze + LDD_REGEX = /\t\S+ => (\S+) \(\S+\)/.freeze + + attr_reader :options + + def initialize(options) + @options = options + end + + def otool_available? + Bundler.which("otool") + end + + def ldd_available? + Bundler.which("ldd") + end + + def dylibs_darwin(path) + output = `/usr/bin/otool -L #{path.shellescape}`.chomp + dylibs = output.split("\n")[1..-1].map {|l| l.match(DARWIN_REGEX).captures[0] }.uniq + # ignore @rpath and friends + dylibs.reject {|dylib| dylib.start_with? "@" } + end + + def dylibs_ldd(path) + output = `/usr/bin/ldd #{path.shellescape}`.chomp + output.split("\n").map do |l| + match = l.match(LDD_REGEX) + next if match.nil? + match.captures[0] + end.compact + end + + def dylibs(path) + case RbConfig::CONFIG["host_os"] + when /darwin/ + return [] unless otool_available? + dylibs_darwin(path) + when /(linux|solaris|bsd)/ + return [] unless ldd_available? + dylibs_ldd(path) + else # Windows, etc. + Bundler.ui.warn("Dynamic library check not supported on this platform.") + [] + end + end + + def bundles_for_gem(spec) + Dir.glob("#{spec.full_gem_path}/**/*.bundle") + end + + def check! + require_relative "check" + Bundler::CLI::Check.new({}).run + end + + def run + Bundler.ui.level = "warn" if options[:quiet] + Bundler.settings.validate! + check! + + definition = Bundler.definition + broken_links = {} + + definition.specs.each do |spec| + bundles_for_gem(spec).each do |bundle| + bad_paths = dylibs(bundle).select do |f| + begin + Fiddle.dlopen(f) + false + rescue Fiddle::DLError + true + end + end + if bad_paths.any? + broken_links[spec] ||= [] + broken_links[spec].concat(bad_paths) + end + end + end + + permissions_valid = check_home_permissions + + if broken_links.any? + message = "The following gems are missing OS dependencies:" + broken_links.map do |spec, paths| + paths.uniq.map do |path| + "\n * #{spec.name}: #{path}" + end + end.flatten.sort.each {|m| message += m } + raise ProductionError, message + elsif !permissions_valid + Bundler.ui.info "No issues found with the installed bundle" + end + end + + private + + def check_home_permissions + require "find" + files_not_readable_or_writable = [] + files_not_rw_and_owned_by_different_user = [] + files_not_owned_by_current_user_but_still_rw = [] + broken_symlinks = [] + Find.find(Bundler.bundle_path.to_s).each do |f| + if !File.exist?(f) + broken_symlinks << f + elsif !File.writable?(f) || !File.readable?(f) + if File.stat(f).uid != Process.uid + files_not_rw_and_owned_by_different_user << f + else + files_not_readable_or_writable << f + end + elsif File.stat(f).uid != Process.uid + files_not_owned_by_current_user_but_still_rw << f + end + end + + ok = true + + if broken_symlinks.any? + Bundler.ui.warn "Broken links exist in the Bundler home. Please report them to the offending gem's upstream repo. These files are:\n - #{broken_symlinks.join("\n - ")}" + + ok = false + end + + if files_not_owned_by_current_user_but_still_rw.any? + Bundler.ui.warn "Files exist in the Bundler home that are owned by another " \ + "user, but are still readable/writable. These files are:\n - #{files_not_owned_by_current_user_but_still_rw.join("\n - ")}" + + ok = false + end + + if files_not_rw_and_owned_by_different_user.any? + Bundler.ui.warn "Files exist in the Bundler home that are owned by another " \ + "user, and are not readable/writable. These files are:\n - #{files_not_rw_and_owned_by_different_user.join("\n - ")}" + + ok = false + end + + if files_not_readable_or_writable.any? + Bundler.ui.warn "Files exist in the Bundler home that are not " \ + "readable/writable by the current user. These files are:\n - #{files_not_readable_or_writable.join("\n - ")}" + + ok = false + end + + ok + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/exec.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/exec.rb new file mode 100644 index 0000000..42b602a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/exec.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +require_relative "../current_ruby" + +module Bundler + class CLI::Exec + attr_reader :options, :args, :cmd + + TRAPPED_SIGNALS = %w[INT].freeze + + def initialize(options, args) + @options = options + @cmd = args.shift + @args = args + @args << { :close_others => !options.keep_file_descriptors? } unless Bundler.current_ruby.jruby? + end + + def run + validate_cmd! + SharedHelpers.set_bundle_environment + if bin_path = Bundler.which(cmd) + if !Bundler.settings[:disable_exec_load] && ruby_shebang?(bin_path) + return kernel_load(bin_path, *args) + end + kernel_exec(bin_path, *args) + else + # exec using the given command + kernel_exec(cmd, *args) + end + end + + private + + def validate_cmd! + return unless cmd.nil? + Bundler.ui.error "bundler: exec needs a command to run" + exit 128 + end + + def kernel_exec(*args) + Kernel.exec(*args) + rescue Errno::EACCES, Errno::ENOEXEC + Bundler.ui.error "bundler: not executable: #{cmd}" + exit 126 + rescue Errno::ENOENT + Bundler.ui.error "bundler: command not found: #{cmd}" + Bundler.ui.warn "Install missing gem executables with `bundle install`" + exit 127 + end + + def kernel_load(file, *args) + args.pop if args.last.is_a?(Hash) + ARGV.replace(args) + $0 = file + Process.setproctitle(process_title(file, args)) if Process.respond_to?(:setproctitle) + require_relative "../setup" + TRAPPED_SIGNALS.each {|s| trap(s, "DEFAULT") } + Kernel.load(file) + rescue SystemExit, SignalException + raise + rescue Exception # rubocop:disable Lint/RescueException + Bundler.ui.error "bundler: failed to load command: #{cmd} (#{file})" + Bundler::FriendlyErrors.disable! + raise + end + + def process_title(file, args) + "#{file} #{args.join(" ")}".strip + end + + def ruby_shebang?(file) + possibilities = [ + "#!/usr/bin/env ruby\n", + "#!/usr/bin/env jruby\n", + "#!/usr/bin/env truffleruby\n", + "#!#{Gem.ruby}\n", + ] + + if File.zero?(file) + Bundler.ui.warn "#{file} is empty" + return false + end + + first_line = File.open(file, "rb") {|f| f.read(possibilities.map(&:size).max) } + possibilities.any? {|shebang| first_line.start_with?(shebang) } + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/fund.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/fund.rb new file mode 100644 index 0000000..52db5ae --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/fund.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Fund + attr_reader :options + + def initialize(options) + @options = options + end + + def run + Bundler.definition.validate_runtime! + + groups = Array(options[:group]).map(&:to_sym) + + deps = if groups.any? + Bundler.definition.dependencies_for(groups) + else + Bundler.definition.current_dependencies + end + + fund_info = deps.each_with_object([]) do |dep, arr| + spec = Bundler.definition.specs[dep.name].first + if spec.metadata.key?("funding_uri") + arr << "* #{spec.name} (#{spec.version})\n Funding: #{spec.metadata["funding_uri"]}" + end + end + + if fund_info.empty? + Bundler.ui.info "None of the installed gems you directly depend on are looking for funding." + else + Bundler.ui.info fund_info.join("\n") + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/gem.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/gem.rb new file mode 100644 index 0000000..c4c76d1 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/gem.rb @@ -0,0 +1,443 @@ +# frozen_string_literal: true + +require "pathname" + +module Bundler + class CLI + Bundler.require_thor_actions + include Thor::Actions + end + + class CLI::Gem + TEST_FRAMEWORK_VERSIONS = { + "rspec" => "3.0", + "minitest" => "5.0", + "test-unit" => "3.0", + }.freeze + + attr_reader :options, :gem_name, :thor, :name, :target + + def initialize(options, gem_name, thor) + @options = options + @gem_name = resolve_name(gem_name) + + @thor = thor + thor.behavior = :invoke + thor.destination_root = nil + + @name = @gem_name + @target = SharedHelpers.pwd.join(gem_name) + + validate_ext_name if options[:ext] + end + + def run + Bundler.ui.confirm "Creating gem '#{name}'..." + + underscored_name = name.tr("-", "_") + namespaced_path = name.tr("-", "/") + constant_name = name.gsub(/-[_-]*(?![_-]|$)/) { "::" }.gsub(/([_-]+|(::)|^)(.|$)/) { $2.to_s + $3.upcase } + constant_array = constant_name.split("::") + minitest_constant_name = constant_array.clone.tap {|a| a[-1] = "Test#{a[-1]}" }.join("::") # Foo::Bar => Foo::TestBar + + use_git = Bundler.git_present? && options[:git] + + git_author_name = use_git ? `git config user.name`.chomp : "" + git_username = use_git ? `git config github.user`.chomp : "" + git_user_email = use_git ? `git config user.email`.chomp : "" + + github_username = if options[:github_username].nil? + git_username + elsif options[:github_username] == false + "" + else + options[:github_username] + end + + config = { + :name => name, + :underscored_name => underscored_name, + :namespaced_path => namespaced_path, + :makefile_path => "#{underscored_name}/#{underscored_name}", + :constant_name => constant_name, + :constant_array => constant_array, + :author => git_author_name.empty? ? "TODO: Write your name" : git_author_name, + :email => git_user_email.empty? ? "TODO: Write your email address" : git_user_email, + :test => options[:test], + :ext => options[:ext], + :exe => options[:exe], + :bundler_version => bundler_dependency_version, + :git => use_git, + :github_username => github_username.empty? ? "[USERNAME]" : github_username, + :required_ruby_version => required_ruby_version, + :minitest_constant_name => minitest_constant_name, + } + ensure_safe_gem_name(name, constant_array) + + templates = { + "#{Bundler.preferred_gemfile_name}.tt" => Bundler.preferred_gemfile_name, + "lib/newgem.rb.tt" => "lib/#{namespaced_path}.rb", + "lib/newgem/version.rb.tt" => "lib/#{namespaced_path}/version.rb", + "sig/newgem.rbs.tt" => "sig/#{namespaced_path}.rbs", + "newgem.gemspec.tt" => "#{name}.gemspec", + "Rakefile.tt" => "Rakefile", + "README.md.tt" => "README.md", + "bin/console.tt" => "bin/console", + "bin/setup.tt" => "bin/setup", + } + + executables = %w[ + bin/console + bin/setup + ] + + templates.merge!("gitignore.tt" => ".gitignore") if use_git + + if test_framework = ask_and_set_test_framework + config[:test] = test_framework + config[:test_framework_version] = TEST_FRAMEWORK_VERSIONS[test_framework] + + case test_framework + when "rspec" + templates.merge!( + "rspec.tt" => ".rspec", + "spec/spec_helper.rb.tt" => "spec/spec_helper.rb", + "spec/newgem_spec.rb.tt" => "spec/#{namespaced_path}_spec.rb" + ) + config[:test_task] = :spec + when "minitest" + # Generate path for minitest target file (FileList["test/**/test_*.rb"]) + # foo => test/test_foo.rb + # foo-bar => test/foo/test_bar.rb + # foo_bar => test/test_foo_bar.rb + paths = namespaced_path.rpartition("/") + paths[2] = "test_#{paths[2]}" + minitest_namespaced_path = paths.join("") + + templates.merge!( + "test/minitest/test_helper.rb.tt" => "test/test_helper.rb", + "test/minitest/test_newgem.rb.tt" => "test/#{minitest_namespaced_path}.rb" + ) + config[:test_task] = :test + when "test-unit" + templates.merge!( + "test/test-unit/test_helper.rb.tt" => "test/test_helper.rb", + "test/test-unit/newgem_test.rb.tt" => "test/#{namespaced_path}_test.rb" + ) + config[:test_task] = :test + end + end + + config[:ci] = ask_and_set_ci + case config[:ci] + when "github" + templates.merge!("github/workflows/main.yml.tt" => ".github/workflows/main.yml") + when "travis" + templates.merge!("travis.yml.tt" => ".travis.yml") + when "gitlab" + templates.merge!("gitlab-ci.yml.tt" => ".gitlab-ci.yml") + when "circle" + templates.merge!("circleci/config.yml.tt" => ".circleci/config.yml") + end + + if ask_and_set(:mit, "Do you want to license your code permissively under the MIT license?", + "This means that any other developer or company will be legally allowed to use your code " \ + "for free as long as they admit you created it. You can read more about the MIT license " \ + "at https://choosealicense.com/licenses/mit.") + config[:mit] = true + Bundler.ui.info "MIT License enabled in config" + templates.merge!("LICENSE.txt.tt" => "LICENSE.txt") + end + + if ask_and_set(:coc, "Do you want to include a code of conduct in gems you generate?", + "Codes of conduct can increase contributions to your project by contributors who " \ + "prefer collaborative, safe spaces. You can read more about the code of conduct at " \ + "contributor-covenant.org. Having a code of conduct means agreeing to the responsibility " \ + "of enforcing it, so be sure that you are prepared to do that. Be sure that your email " \ + "address is specified as a contact in the generated code of conduct so that people know " \ + "who to contact in case of a violation. For suggestions about " \ + "how to enforce codes of conduct, see https://bit.ly/coc-enforcement.") + config[:coc] = true + Bundler.ui.info "Code of conduct enabled in config" + templates.merge!("CODE_OF_CONDUCT.md.tt" => "CODE_OF_CONDUCT.md") + end + + if ask_and_set(:changelog, "Do you want to include a changelog?", + "A changelog is a file which contains a curated, chronologically ordered list of notable " \ + "changes for each version of a project. To make it easier for users and contributors to" \ + " see precisely what notable changes have been made between each release (or version) of" \ + " the project. Whether consumers or developers, the end users of software are" \ + " human beings who care about what's in the software. When the software changes, people " \ + "want to know why and how. see https://keepachangelog.com") + config[:changelog] = true + Bundler.ui.info "Changelog enabled in config" + templates.merge!("CHANGELOG.md.tt" => "CHANGELOG.md") + end + + config[:linter] = ask_and_set_linter + case config[:linter] + when "rubocop" + config[:linter_version] = rubocop_version + Bundler.ui.info "RuboCop enabled in config" + templates.merge!("rubocop.yml.tt" => ".rubocop.yml") + when "standard" + config[:linter_version] = standard_version + Bundler.ui.info "Standard enabled in config" + templates.merge!("standard.yml.tt" => ".standard.yml") + end + + templates.merge!("exe/newgem.tt" => "exe/#{name}") if config[:exe] + + if options[:ext] + templates.merge!( + "ext/newgem/extconf.rb.tt" => "ext/#{name}/extconf.rb", + "ext/newgem/newgem.h.tt" => "ext/#{name}/#{underscored_name}.h", + "ext/newgem/newgem.c.tt" => "ext/#{name}/#{underscored_name}.c" + ) + end + + if target.exist? && !target.directory? + Bundler.ui.error "Couldn't create a new gem named `#{gem_name}` because there's an existing file named `#{gem_name}`." + exit Bundler::BundlerError.all_errors[Bundler::GenericSystemCallError] + end + + if use_git + Bundler.ui.info "Initializing git repo in #{target}" + require "shellwords" + `git init #{target.to_s.shellescape}` + + config[:git_default_branch] = File.read("#{target}/.git/HEAD").split("/").last.chomp + end + + templates.each do |src, dst| + destination = target.join(dst) + thor.template("newgem/#{src}", destination, config) + end + + executables.each do |file| + path = target.join(file) + executable = (path.stat.mode | 0o111) + path.chmod(executable) + end + + if use_git + Dir.chdir(target) do + `git add .` + end + end + + # Open gemspec in editor + open_editor(options["edit"], target.join("#{name}.gemspec")) if options[:edit] + + Bundler.ui.info "Gem '#{name}' was successfully created. " \ + "For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html" + end + + private + + def resolve_name(name) + SharedHelpers.pwd.join(name).basename.to_s + end + + def ask_and_set(key, header, message) + choice = options[key] + choice = Bundler.settings["gem.#{key}"] if choice.nil? + + if choice.nil? + Bundler.ui.confirm header + choice = Bundler.ui.yes? "#{message} y/(n):" + Bundler.settings.set_global("gem.#{key}", choice) + end + + choice + end + + def validate_ext_name + return unless gem_name.index("-") + + Bundler.ui.error "You have specified a gem name which does not conform to the \n" \ + "naming guidelines for C extensions. For more information, \n" \ + "see the 'Extension Naming' section at the following URL:\n" \ + "https://guides.rubygems.org/gems-with-extensions/\n" + exit 1 + end + + def ask_and_set_test_framework + test_framework = options[:test] || Bundler.settings["gem.test"] + + if test_framework.to_s.empty? + Bundler.ui.confirm "Do you want to generate tests with your gem?" + Bundler.ui.info hint_text("test") + + result = Bundler.ui.ask "Enter a test framework. rspec/minitest/test-unit/(none):" + if result =~ /rspec|minitest|test-unit/ + test_framework = result + else + test_framework = false + end + end + + if Bundler.settings["gem.test"].nil? + Bundler.settings.set_global("gem.test", test_framework) + end + + if options[:test] == Bundler.settings["gem.test"] + Bundler.ui.info "#{options[:test]} is already configured, ignoring --test flag." + end + + test_framework + end + + def hint_text(setting) + if Bundler.settings["gem.#{setting}"] == false + "Your choice will only be applied to this gem." + else + "Future `bundle gem` calls will use your choice. " \ + "This setting can be changed anytime with `bundle config gem.#{setting}`." + end + end + + def ask_and_set_ci + ci_template = options[:ci] || Bundler.settings["gem.ci"] + + if ci_template.to_s.empty? + Bundler.ui.confirm "Do you want to set up continuous integration for your gem? " \ + "Supported services:\n" \ + "* CircleCI: https://circleci.com/\n" \ + "* GitHub Actions: https://github.com/features/actions\n" \ + "* GitLab CI: https://docs.gitlab.com/ee/ci/\n" \ + "* Travis CI: https://travis-ci.org/\n" \ + "\n" + Bundler.ui.info hint_text("ci") + + result = Bundler.ui.ask "Enter a CI service. github/travis/gitlab/circle/(none):" + if result =~ /github|travis|gitlab|circle/ + ci_template = result + else + ci_template = false + end + end + + if Bundler.settings["gem.ci"].nil? + Bundler.settings.set_global("gem.ci", ci_template) + end + + if options[:ci] == Bundler.settings["gem.ci"] + Bundler.ui.info "#{options[:ci]} is already configured, ignoring --ci flag." + end + + ci_template + end + + def ask_and_set_linter + linter_template = options[:linter] || Bundler.settings["gem.linter"] + linter_template = deprecated_rubocop_option if linter_template.nil? + + if linter_template.to_s.empty? + Bundler.ui.confirm "Do you want to add a code linter and formatter to your gem? " \ + "Supported Linters:\n" \ + "* RuboCop: https://rubocop.org\n" \ + "* Standard: https://github.com/testdouble/standard\n" \ + "\n" + Bundler.ui.info hint_text("linter") + + result = Bundler.ui.ask "Enter a linter. rubocop/standard/(none):" + if result =~ /rubocop|standard/ + linter_template = result + else + linter_template = false + end + end + + if Bundler.settings["gem.linter"].nil? + Bundler.settings.set_global("gem.linter", linter_template) + end + + # Once gem.linter safely set, unset the deprecated gem.rubocop + unless Bundler.settings["gem.rubocop"].nil? + Bundler.settings.set_global("gem.rubocop", nil) + end + + if options[:linter] == Bundler.settings["gem.linter"] + Bundler.ui.info "#{options[:linter]} is already configured, ignoring --linter flag." + end + + linter_template + end + + def deprecated_rubocop_option + if !options[:rubocop].nil? + if options[:rubocop] + Bundler::SharedHelpers.major_deprecation 2, "--rubocop is deprecated, use --linter=rubocop" + "rubocop" + else + Bundler::SharedHelpers.major_deprecation 2, "--no-rubocop is deprecated, use --linter" + false + end + elsif !Bundler.settings["gem.rubocop"].nil? + Bundler::SharedHelpers.major_deprecation 2, + "config gem.rubocop is deprecated; we've updated your config to use gem.linter instead" + Bundler.settings["gem.rubocop"] ? "rubocop" : false + end + end + + def bundler_dependency_version + v = Gem::Version.new(Bundler::VERSION) + req = v.segments[0..1] + req << "a" if v.prerelease? + req.join(".") + end + + def ensure_safe_gem_name(name, constant_array) + if name =~ /^\d/ + Bundler.ui.error "Invalid gem name #{name} Please give a name which does not start with numbers." + exit 1 + end + + constant_name = constant_array.join("::") + + existing_constant = constant_array.inject(Object) do |c, s| + defined = begin + c.const_defined?(s) + rescue NameError + Bundler.ui.error "Invalid gem name #{name} -- `#{constant_name}` is an invalid constant name" + exit 1 + end + (defined && c.const_get(s)) || break + end + + return unless existing_constant + Bundler.ui.error "Invalid gem name #{name} constant #{constant_name} is already in use. Please choose another gem name." + exit 1 + end + + def open_editor(editor, file) + thor.run(%(#{editor} "#{file}")) + end + + def required_ruby_version + if Gem.ruby_version < Gem::Version.new("2.4.a") then "2.3.0" + elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "2.4.0" + elsif Gem.ruby_version < Gem::Version.new("2.6.a") then "2.5.0" + else + "2.6.0" + end + end + + def rubocop_version + if Gem.ruby_version < Gem::Version.new("2.4.a") then "0.81.0" + elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "1.12" + else + "1.21" + end + end + + def standard_version + if Gem.ruby_version < Gem::Version.new("2.4.a") then "0.2.5" + elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "1.0" + else + "1.3" + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/info.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/info.rb new file mode 100644 index 0000000..0545ce8 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/info.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Info + attr_reader :gem_name, :options + def initialize(options, gem_name) + @options = options + @gem_name = gem_name + end + + def run + Bundler.ui.silence do + Bundler.definition.validate_runtime! + Bundler.load.lock + end + + spec = spec_for_gem(gem_name) + + if spec + return print_gem_path(spec) if @options[:path] + return print_gem_version(spec) if @options[:version] + print_gem_info(spec) + end + end + + private + + def spec_for_gem(gem_name) + spec = Bundler.definition.specs.find {|s| s.name == gem_name } + spec || default_gem_spec(gem_name) || Bundler::CLI::Common.select_spec(gem_name, :regex_match) + end + + def default_gem_spec(gem_name) + return unless Gem::Specification.respond_to?(:find_all_by_name) + gem_spec = Gem::Specification.find_all_by_name(gem_name).last + return gem_spec if gem_spec && gem_spec.respond_to?(:default_gem?) && gem_spec.default_gem? + end + + def spec_not_found(gem_name) + raise GemNotFound, Bundler::CLI::Common.gem_not_found_message(gem_name, Bundler.definition.dependencies) + end + + def print_gem_version(spec) + Bundler.ui.info spec.version.to_s + end + + def print_gem_path(spec) + name = spec.name + if name == "bundler" + path = File.expand_path("../../..", __dir__) + else + path = spec.full_gem_path + if spec.deleted_gem? + return Bundler.ui.warn "The gem #{name} has been deleted. It was installed at: #{path}" + end + end + + Bundler.ui.info path + end + + def print_gem_info(spec) + metadata = spec.metadata + name = spec.name + gem_info = String.new + gem_info << " * #{name} (#{spec.version}#{spec.git_version})\n" + gem_info << "\tSummary: #{spec.summary}\n" if spec.summary + gem_info << "\tHomepage: #{spec.homepage}\n" if spec.homepage + gem_info << "\tDocumentation: #{metadata["documentation_uri"]}\n" if metadata.key?("documentation_uri") + gem_info << "\tSource Code: #{metadata["source_code_uri"]}\n" if metadata.key?("source_code_uri") + gem_info << "\tFunding: #{metadata["funding_uri"]}\n" if metadata.key?("funding_uri") + gem_info << "\tWiki: #{metadata["wiki_uri"]}\n" if metadata.key?("wiki_uri") + gem_info << "\tChangelog: #{metadata["changelog_uri"]}\n" if metadata.key?("changelog_uri") + gem_info << "\tBug Tracker: #{metadata["bug_tracker_uri"]}\n" if metadata.key?("bug_tracker_uri") + gem_info << "\tMailing List: #{metadata["mailing_list_uri"]}\n" if metadata.key?("mailing_list_uri") + gem_info << "\tPath: #{spec.full_gem_path}\n" + gem_info << "\tDefault Gem: yes\n" if spec.respond_to?(:default_gem?) && spec.default_gem? + gem_info << "\tReverse Dependencies: \n\t\t#{gem_dependencies.join("\n\t\t")}" if gem_dependencies.any? + + if name != "bundler" && spec.deleted_gem? + return Bundler.ui.warn "The gem #{name} has been deleted. Gemspec information is still available though:\n#{gem_info}" + end + + Bundler.ui.info gem_info + end + + def gem_dependencies + @gem_dependencies ||= Bundler.definition.specs.map do |spec| + dependency = spec.dependencies.find {|dep| dep.name == gem_name } + next unless dependency + "#{spec.name} (#{spec.version}) depends on #{gem_name} (#{dependency.requirements_list.join(", ")})" + end.compact.sort + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/init.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/init.rb new file mode 100644 index 0000000..bc96507 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/init.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Init + attr_reader :options + def initialize(options) + @options = options + end + + def run + if File.exist?(gemfile) + Bundler.ui.error "#{gemfile} already exists at #{File.expand_path(gemfile)}" + exit 1 + end + + unless File.writable?(Dir.pwd) + Bundler.ui.error "Can not create #{gemfile} as the current directory is not writable." + exit 1 + end + + if options[:gemspec] + gemspec = File.expand_path(options[:gemspec]) + unless File.exist?(gemspec) + Bundler.ui.error "Gem specification #{gemspec} doesn't exist" + exit 1 + end + + spec = Bundler.load_gemspec_uncached(gemspec) + + File.open(gemfile, "wb") do |file| + file << "# Generated from #{gemspec}\n" + file << spec.to_gemfile + end + else + File.open(File.expand_path("../templates/#{gemfile}", __dir__), "r") do |template| + File.open(gemfile, "wb") do |destination| + IO.copy_stream(template, destination) + end + end + end + + puts "Writing new #{gemfile} to #{SharedHelpers.pwd}/#{gemfile}" + end + + private + + def gemfile + @gemfile ||= Bundler.preferred_gemfile_name + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/inject.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/inject.rb new file mode 100644 index 0000000..8093a85 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/inject.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Inject + attr_reader :options, :name, :version, :group, :source, :gems + def initialize(options, name, version) + @options = options + @name = name + @version = version || last_version_number + @group = options[:group].split(",") unless options[:group].nil? + @source = options[:source] + @gems = [] + end + + def run + # The required arguments allow Thor to give useful feedback when the arguments + # are incorrect. This adds those first two arguments onto the list as a whole. + gems.unshift(source).unshift(group).unshift(version).unshift(name) + + # Build an array of Dependency objects out of the arguments + deps = [] + # when `inject` support addition of more than one gem, then this loop will + # help. Currently this loop is running once. + gems.each_slice(4) do |gem_name, gem_version, gem_group, gem_source| + ops = Gem::Requirement::OPS.map {|key, _val| key } + has_op = ops.any? {|op| gem_version.start_with? op } + gem_version = "~> #{gem_version}" unless has_op + deps << Bundler::Dependency.new(gem_name, gem_version, "group" => gem_group, "source" => gem_source) + end + + added = Injector.inject(deps, options) + + if added.any? + Bundler.ui.confirm "Added to Gemfile:" + Bundler.ui.confirm(added.map do |d| + name = "'#{d.name}'" + requirement = ", '#{d.requirement}'" + group = ", :group => #{d.groups.inspect}" if d.groups != Array(:default) + source = ", :source => '#{d.source}'" unless d.source.nil? + %(gem #{name}#{requirement}#{group}#{source}) + end.join("\n")) + else + Bundler.ui.confirm "All gems were already present in the Gemfile" + end + end + + private + + def last_version_number + definition = Bundler.definition(true) + definition.resolve_remotely! + specs = definition.index[name].sort_by(&:version) + unless options[:pre] + specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? } + end + spec = specs.last + spec.version.to_s + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/install.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/install.rb new file mode 100644 index 0000000..851ae9b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/install.rb @@ -0,0 +1,190 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Install + attr_reader :options + def initialize(options) + @options = options + end + + def run + Bundler.ui.level = "warn" if options[:quiet] + + warn_if_root + + Bundler.self_manager.install_locked_bundler_and_restart_with_it_if_needed + + Bundler::SharedHelpers.set_env "RB_USER_INSTALL", "1" if Bundler::FREEBSD + + # Disable color in deployment mode + Bundler.ui.shell = Thor::Shell::Basic.new if options[:deployment] + + check_for_options_conflicts + + check_trust_policy + + if options[:deployment] || options[:frozen] || Bundler.frozen_bundle? + unless Bundler.default_lockfile.exist? + flag = "--deployment flag" if options[:deployment] + flag ||= "--frozen flag" if options[:frozen] + flag ||= "deployment setting" + raise ProductionError, "The #{flag} requires a #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}. Please make " \ + "sure you have checked your #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} into version control " \ + "before deploying." + end + + options[:local] = true if Bundler.app_cache.exist? + + Bundler.settings.set_command_option :deployment, true if options[:deployment] + Bundler.settings.set_command_option :frozen, true if options[:frozen] + end + + # When install is called with --no-deployment, disable deployment mode + if options[:deployment] == false + Bundler.settings.set_command_option :frozen, nil + options[:system] = true + end + + normalize_settings + + Bundler::Fetcher.disable_endpoint = options["full-index"] + + if options["binstubs"] + Bundler::SharedHelpers.major_deprecation 2, + "The --binstubs option will be removed in favor of `bundle binstubs --all`" + end + + Plugin.gemfile_install(Bundler.default_gemfile) if Bundler.feature_flag.plugins? + + definition = Bundler.definition + definition.validate_runtime! + + installer = Installer.install(Bundler.root, definition, options) + + Bundler.settings.temporary(:cache_all_platforms => options[:local] ? false : Bundler.settings[:cache_all_platforms]) do + Bundler.load.cache(nil, options[:local]) if Bundler.app_cache.exist? && !options["no-cache"] && !Bundler.frozen_bundle? + end + + Bundler.ui.confirm "Bundle complete! #{dependencies_count_for(definition)}, #{gems_installed_for(definition)}." + Bundler::CLI::Common.output_without_groups_message(:install) + + if Bundler.use_system_gems? + Bundler.ui.confirm "Use `bundle info [gemname]` to see where a bundled gem is installed." + else + relative_path = Bundler.configured_bundle_path.base_path_relative_to_pwd + Bundler.ui.confirm "Bundled gems are installed into `#{relative_path}`" + end + + Bundler::CLI::Common.output_post_install_messages installer.post_install_messages + + warn_ambiguous_gems + + if CLI::Common.clean_after_install? + require_relative "clean" + Bundler::CLI::Clean.new(options).run + end + + Bundler::CLI::Common.output_fund_metadata_summary + rescue Gem::InvalidSpecificationException + Bundler.ui.warn "You have one or more invalid gemspecs that need to be fixed." + raise + end + + private + + def warn_if_root + return if Bundler.settings[:silence_root_warning] || Gem.win_platform? || !Process.uid.zero? + Bundler.ui.warn "Don't run Bundler as root. Bundler can ask for sudo " \ + "if it is needed, and installing your bundle as root will break this " \ + "application for all non-root users on this machine.", :wrap => true + end + + def dependencies_count_for(definition) + count = definition.dependencies.count + "#{count} Gemfile #{count == 1 ? "dependency" : "dependencies"}" + end + + def gems_installed_for(definition) + count = definition.specs.count + "#{count} #{count == 1 ? "gem" : "gems"} now installed" + end + + def check_for_group_conflicts_in_cli_options + conflicting_groups = Array(options[:without]) & Array(options[:with]) + return if conflicting_groups.empty? + raise InvalidOption, "You can't list a group in both with and without." \ + " The offending groups are: #{conflicting_groups.join(", ")}." + end + + def check_for_options_conflicts + if (options[:path] || options[:deployment]) && options[:system] + error_message = String.new + error_message << "You have specified both --path as well as --system. Please choose only one option.\n" if options[:path] + error_message << "You have specified both --deployment as well as --system. Please choose only one option.\n" if options[:deployment] + raise InvalidOption.new(error_message) + end + end + + def check_trust_policy + trust_policy = options["trust-policy"] + unless Bundler.rubygems.security_policies.keys.unshift(nil).include?(trust_policy) + raise InvalidOption, "RubyGems doesn't know about trust policy '#{trust_policy}'. " \ + "The known policies are: #{Bundler.rubygems.security_policies.keys.join(", ")}." + end + Bundler.settings.set_command_option_if_given :"trust-policy", trust_policy + end + + def normalize_groups + check_for_group_conflicts_in_cli_options + + # need to nil them out first to get around validation for backwards compatibility + Bundler.settings.set_command_option :without, nil + Bundler.settings.set_command_option :with, nil + Bundler.settings.set_command_option :without, options[:without] + Bundler.settings.set_command_option :with, options[:with] + end + + def normalize_settings + Bundler.settings.set_command_option :path, nil if options[:system] + Bundler.settings.set_command_option_if_given :path, options[:path] + + if options["standalone"] && Bundler.settings[:path].nil? && !options["local"] + Bundler.settings.temporary(:path_relative_to_cwd => false) do + Bundler.settings.set_command_option :path, "bundle" + end + end + + bin_option = options["binstubs"] + bin_option = nil if bin_option && bin_option.empty? + Bundler.settings.set_command_option :bin, bin_option if options["binstubs"] + + Bundler.settings.set_command_option_if_given :shebang, options["shebang"] + + Bundler.settings.set_command_option_if_given :jobs, options["jobs"] + + Bundler.settings.set_command_option_if_given :no_prune, options["no-prune"] + + Bundler.settings.set_command_option_if_given :no_install, options["no-install"] + + Bundler.settings.set_command_option_if_given :clean, options["clean"] + + normalize_groups if options[:without] || options[:with] + + options[:force] = options[:redownload] + end + + def warn_ambiguous_gems + # TODO: remove this when we drop Bundler 1.x support + Installer.ambiguous_gems.to_a.each do |name, installed_from_uri, *also_found_in_uris| + Bundler.ui.warn "Warning: the gem '#{name}' was found in multiple sources." + Bundler.ui.warn "Installed from: #{installed_from_uri}" + Bundler.ui.warn "Also found in:" + also_found_in_uris.each {|uri| Bundler.ui.warn " * #{uri}" } + Bundler.ui.warn "You should add a source requirement to restrict this gem to your preferred source." + Bundler.ui.warn "For example:" + Bundler.ui.warn " gem '#{name}', :source => '#{installed_from_uri}'" + Bundler.ui.warn "Then uninstall the gem '#{name}' (or delete all bundled gems) and then install again." + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/issue.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/issue.rb new file mode 100644 index 0000000..b891ecb --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/issue.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require "rbconfig" + +module Bundler + class CLI::Issue + def run + Bundler.ui.info <<-EOS.gsub(/^ {8}/, "") + Did you find an issue with Bundler? Before filing a new issue, + be sure to check out these resources: + + 1. Check out our troubleshooting guide for quick fixes to common issues: + https://github.com/rubygems/rubygems/blob/master/bundler/doc/TROUBLESHOOTING.md + + 2. Instructions for common Bundler uses can be found on the documentation + site: https://bundler.io/ + + 3. Information about each Bundler command can be found in the Bundler + man pages: https://bundler.io/man/bundle.1.html + + Hopefully the troubleshooting steps above resolved your problem! If things + still aren't working the way you expect them to, please let us know so + that we can diagnose and help fix the problem you're having, by filling + in the new issue form located at + https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md, + and copy and pasting the information below. + + EOS + + Bundler.ui.info Bundler::Env.report + + Bundler.ui.info "\n## Bundle Doctor" + doctor + end + + def doctor + require_relative "doctor" + Bundler::CLI::Doctor.new({}).run + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/list.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/list.rb new file mode 100644 index 0000000..f56bf5b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/list.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module Bundler + class CLI::List + def initialize(options) + @options = options + @without_group = options["without-group"].map(&:to_sym) + @only_group = options["only-group"].map(&:to_sym) + end + + def run + raise InvalidOption, "The `--only-group` and `--without-group` options cannot be used together" if @only_group.any? && @without_group.any? + + raise InvalidOption, "The `--name-only` and `--paths` options cannot be used together" if @options["name-only"] && @options[:paths] + + specs = if @only_group.any? || @without_group.any? + filtered_specs_by_groups + else + begin + Bundler.load.specs + rescue GemNotFound => e + Bundler.ui.error e.message + Bundler.ui.warn "Install missing gems with `bundle install`." + exit 1 + end + end.reject {|s| s.name == "bundler" }.sort_by(&:name) + + return Bundler.ui.info "No gems in the Gemfile" if specs.empty? + + return specs.each {|s| Bundler.ui.info s.name } if @options["name-only"] + return specs.each {|s| Bundler.ui.info s.full_gem_path } if @options["paths"] + + Bundler.ui.info "Gems included by the bundle:" + + specs.each {|s| Bundler.ui.info " * #{s.name} (#{s.version}#{s.git_version})" } + + Bundler.ui.info "Use `bundle info` to print more detailed information about a gem" + end + + private + + def verify_group_exists(groups) + (@without_group + @only_group).each do |group| + raise InvalidOption, "`#{group}` group could not be found." unless groups.include?(group) + end + end + + def filtered_specs_by_groups + definition = Bundler.definition + groups = definition.groups + + verify_group_exists(groups) + + show_groups = + if @without_group.any? + groups.reject {|g| @without_group.include?(g) } + elsif @only_group.any? + groups.select {|g| @only_group.include?(g) } + else + groups + end.map(&:to_sym) + + definition.specs_for(show_groups) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/lock.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/lock.rb new file mode 100644 index 0000000..7d613a6 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/lock.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Lock + attr_reader :options + + def initialize(options) + @options = options + end + + def run + unless Bundler.default_gemfile + Bundler.ui.error "Unable to find a Gemfile to lock" + exit 1 + end + + print = options[:print] + ui = Bundler.ui + Bundler.ui = UI::Silent.new if print + + Bundler::Fetcher.disable_endpoint = options["full-index"] + + update = options[:update] + conservative = options[:conservative] + + if update.is_a?(Array) # unlocking specific gems + Bundler::CLI::Common.ensure_all_gems_in_lockfile!(update) + update = { :gems => update, :conservative => conservative } + elsif update + update = { :conservative => conservative } if conservative + end + definition = Bundler.definition(update) + + Bundler::CLI::Common.configure_gem_version_promoter(Bundler.definition, options) if options[:update] + + options["remove-platform"].each do |platform| + definition.remove_platform(platform) + end + + options["add-platform"].each do |platform_string| + platform = Gem::Platform.new(platform_string) + if platform.to_s == "unknown" + Bundler.ui.warn "The platform `#{platform_string}` is unknown to RubyGems " \ + "and adding it will likely lead to resolution errors" + end + definition.add_platform(platform) + end + + if definition.platforms.empty? + raise InvalidOption, "Removing all platforms from the bundle is not allowed" + end + + definition.resolve_remotely! unless options[:local] + + if print + puts definition.to_lock + else + file = options[:lockfile] + file = file ? File.expand_path(file) : Bundler.default_lockfile + puts "Writing lockfile to #{file}" + definition.lock(file) + end + + Bundler.ui = ui + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/open.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/open.rb new file mode 100644 index 0000000..ea50434 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/open.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Open + attr_reader :options, :name + def initialize(options, name) + @options = options + @name = name + end + + def run + editor = [ENV["BUNDLER_EDITOR"], ENV["VISUAL"], ENV["EDITOR"]].find {|e| !e.nil? && !e.empty? } + return Bundler.ui.info("To open a bundled gem, set $EDITOR or $BUNDLER_EDITOR") unless editor + return unless spec = Bundler::CLI::Common.select_spec(name, :regex_match) + if spec.default_gem? + Bundler.ui.info "Unable to open #{name} because it's a default gem, so the directory it would normally be installed to does not exist." + else + path = spec.full_gem_path + Dir.chdir(path) do + require "shellwords" + command = Shellwords.split(editor) + [path] + Bundler.with_original_env do + system(*command) + end || Bundler.ui.info("Could not run '#{command.join(" ")}'") + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/outdated.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/outdated.rb new file mode 100644 index 0000000..e9f93fe --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/outdated.rb @@ -0,0 +1,299 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Outdated + attr_reader :options, :gems, :options_include_groups, :filter_options_patch, :sources, :strict + attr_accessor :outdated_gems + + def initialize(options, gems) + @options = options + @gems = gems + @sources = Array(options[:source]) + + @filter_options_patch = options.keys & %w[filter-major filter-minor filter-patch] + + @outdated_gems = [] + + @options_include_groups = [:group, :groups].any? do |v| + options.keys.include?(v.to_s) + end + + # the patch level options imply strict is also true. It wouldn't make + # sense otherwise. + @strict = options["filter-strict"] || Bundler::CLI::Common.patch_level_options(options).any? + end + + def run + check_for_deployment_mode! + + gems.each do |gem_name| + Bundler::CLI::Common.select_spec(gem_name) + end + + Bundler.definition.validate_runtime! + current_specs = Bundler.ui.silence { Bundler.definition.resolve } + + current_dependencies = Bundler.ui.silence do + Bundler.load.dependencies.map {|dep| [dep.name, dep] }.to_h + end + + definition = if gems.empty? && sources.empty? + # We're doing a full update + Bundler.definition(true) + else + Bundler.definition(:gems => gems, :sources => sources) + end + + Bundler::CLI::Common.configure_gem_version_promoter( + Bundler.definition, + options.merge(:strict => @strict) + ) + + definition_resolution = proc do + options[:local] ? definition.resolve_with_cache! : definition.resolve_remotely! + end + + if options[:parseable] + Bundler.ui.silence(&definition_resolution) + else + definition_resolution.call + end + + Bundler.ui.info "" + + # Loop through the current specs + gemfile_specs, dependency_specs = current_specs.partition do |spec| + current_dependencies.key? spec.name + end + + specs = if options["only-explicit"] + gemfile_specs + else + gemfile_specs + dependency_specs + end + + specs.sort_by(&:name).uniq(&:name).each do |current_spec| + next unless gems.empty? || gems.include?(current_spec.name) + + active_spec = retrieve_active_spec(definition, current_spec) + next unless active_spec + + next unless filter_options_patch.empty? || update_present_via_semver_portions(current_spec, active_spec, options) + + gem_outdated = Gem::Version.new(active_spec.version) > Gem::Version.new(current_spec.version) + next unless gem_outdated || (current_spec.git_version != active_spec.git_version) + + dependency = current_dependencies[current_spec.name] + groups = "" + if dependency && !options[:parseable] + groups = dependency.groups.join(", ") + end + + outdated_gems << { + :active_spec => active_spec, + :current_spec => current_spec, + :dependency => dependency, + :groups => groups, + } + end + + if outdated_gems.empty? + unless options[:parseable] + Bundler.ui.info(nothing_outdated_message) + end + else + if options_include_groups + relevant_outdated_gems = outdated_gems.group_by {|g| g[:groups] }.sort.flat_map do |groups, gems| + contains_group = groups.split(", ").include?(options[:group]) + next unless options[:groups] || contains_group + + gems + end.compact + + if options[:parseable] + relevant_outdated_gems.each do |gems| + print_gems(gems) + end + else + print_gems_table(relevant_outdated_gems) + end + elsif options[:parseable] + print_gems(outdated_gems) + else + print_gems_table(outdated_gems) + end + + exit 1 + end + end + + private + + def loaded_from_for(spec) + return unless spec.respond_to?(:loaded_from) + + spec.loaded_from + end + + def groups_text(group_text, groups) + "#{group_text}#{groups.split(",").size > 1 ? "s" : ""} \"#{groups}\"" + end + + def nothing_outdated_message + if filter_options_patch.any? + display = filter_options_patch.map do |o| + o.sub("filter-", "") + end.join(" or ") + + "No #{display} updates to display.\n" + else + "Bundle up to date!\n" + end + end + + def retrieve_active_spec(definition, current_spec) + active_spec = definition.resolve.find_by_name_and_platform(current_spec.name, current_spec.platform) + return unless active_spec + + return active_spec if strict + + active_specs = active_spec.source.specs.search(current_spec.name).select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version) + if !current_spec.version.prerelease? && !options[:pre] && active_specs.size > 1 + active_specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? } + end + active_specs.last + end + + def print_gems(gems_list) + gems_list.each do |gem| + print_gem( + gem[:current_spec], + gem[:active_spec], + gem[:dependency], + gem[:groups], + ) + end + end + + def print_gems_table(gems_list) + data = gems_list.map do |gem| + gem_column_for( + gem[:current_spec], + gem[:active_spec], + gem[:dependency], + gem[:groups], + ) + end + + print_indented([table_header] + data) + end + + def print_gem(current_spec, active_spec, dependency, groups) + spec_version = "#{active_spec.version}#{active_spec.git_version}" + if Bundler.ui.debug? + loaded_from = loaded_from_for(active_spec) + spec_version += " (from #{loaded_from})" if loaded_from + end + current_version = "#{current_spec.version}#{current_spec.git_version}" + + if dependency && dependency.specific? + dependency_version = %(, requested #{dependency.requirement}) + end + + spec_outdated_info = "#{active_spec.name} (newest #{spec_version}, " \ + "installed #{current_version}#{dependency_version})" + + output_message = if options[:parseable] + spec_outdated_info.to_s + elsif options_include_groups || groups.empty? + " * #{spec_outdated_info}" + else + " * #{spec_outdated_info} in #{groups_text("group", groups)}" + end + + Bundler.ui.info output_message.rstrip + end + + def gem_column_for(current_spec, active_spec, dependency, groups) + current_version = "#{current_spec.version}#{current_spec.git_version}" + spec_version = "#{active_spec.version}#{active_spec.git_version}" + dependency = dependency.requirement if dependency + + ret_val = [active_spec.name, current_version, spec_version, dependency.to_s, groups.to_s] + ret_val << loaded_from_for(active_spec).to_s if Bundler.ui.debug? + ret_val + end + + def check_for_deployment_mode! + return unless Bundler.frozen_bundle? + suggested_command = if Bundler.settings.locations("frozen").keys.&([:global, :local]).any? + "bundle config unset frozen" + elsif Bundler.settings.locations("deployment").keys.&([:global, :local]).any? + "bundle config unset deployment" + end + raise ProductionError, "You are trying to check outdated gems in " \ + "deployment mode. Run `bundle outdated` elsewhere.\n" \ + "\nIf this is a development machine, remove the " \ + "#{Bundler.default_gemfile} freeze" \ + "\nby running `#{suggested_command}`." + end + + def update_present_via_semver_portions(current_spec, active_spec, options) + current_major = current_spec.version.segments.first + active_major = active_spec.version.segments.first + + update_present = false + update_present = active_major > current_major if options["filter-major"] + + if !update_present && (options["filter-minor"] || options["filter-patch"]) && current_major == active_major + current_minor = get_version_semver_portion_value(current_spec, 1) + active_minor = get_version_semver_portion_value(active_spec, 1) + + update_present = active_minor > current_minor if options["filter-minor"] + + if !update_present && options["filter-patch"] && current_minor == active_minor + current_patch = get_version_semver_portion_value(current_spec, 2) + active_patch = get_version_semver_portion_value(active_spec, 2) + + update_present = active_patch > current_patch + end + end + + update_present + end + + def get_version_semver_portion_value(spec, version_portion_index) + version_section = spec.version.segments[version_portion_index, 1] + version_section.to_a[0].to_i + end + + def print_indented(matrix) + header = matrix[0] + data = matrix[1..-1] + + column_sizes = Array.new(header.size) do |index| + matrix.max_by {|row| row[index].length }[index].length + end + + Bundler.ui.info justify(header, column_sizes) + + data.sort_by! {|row| row[0] } + + data.each do |row| + Bundler.ui.info justify(row, column_sizes) + end + end + + def table_header + header = ["Gem", "Current", "Latest", "Requested", "Groups"] + header << "Path" if Bundler.ui.debug? + header + end + + def justify(row, sizes) + row.each_with_index.map do |element, index| + element.ljust(sizes[index]) + end.join(" ").strip + "\n" + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/platform.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/platform.rb new file mode 100644 index 0000000..73da8cf --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/platform.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Platform + attr_reader :options + def initialize(options) + @options = options + end + + def run + platforms, ruby_version = Bundler.ui.silence do + locked_ruby_version = Bundler.locked_gems && Bundler.locked_gems.ruby_version&.gsub(/p\d+\Z/, "") + gemfile_ruby_version = Bundler.definition.ruby_version && Bundler.definition.ruby_version.single_version_string + [Bundler.definition.platforms.map {|p| "* #{p}" }, + locked_ruby_version || gemfile_ruby_version] + end + output = [] + + if options[:ruby] + if ruby_version + output << ruby_version + else + output << "No ruby version specified" + end + else + output << "Your platform is: #{Gem::Platform.local}" + output << "Your app has gems that work on these platforms:\n#{platforms.join("\n")}" + + if ruby_version + output << "Your Gemfile specifies a Ruby version requirement:\n* #{ruby_version}" + + begin + Bundler.definition.validate_runtime! + output << "Your current platform satisfies the Ruby version requirement." + rescue RubyVersionMismatch => e + output << e.message + end + else + output << "Your Gemfile does not specify a Ruby version requirement." + end + end + + Bundler.ui.info output.join("\n\n") + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/plugin.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/plugin.rb new file mode 100644 index 0000000..fe3f441 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/plugin.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require_relative "../vendored_thor" +module Bundler + class CLI::Plugin < Thor + desc "install PLUGINS", "Install the plugin from the source" + long_desc <<-D + Install plugins either from the rubygems source provided (with --source option) or from a git source provided with --git (for remote repos) or --local_git (for local repos). If no sources are provided, it uses Gem.sources + D + method_option "source", :type => :string, :default => nil, :banner => + "URL of the RubyGems source to fetch the plugin from" + method_option "version", :type => :string, :default => nil, :banner => + "The version of the plugin to fetch" + method_option "git", :type => :string, :default => nil, :banner => + "URL of the git repo to fetch from" + method_option "local_git", :type => :string, :default => nil, :banner => + "Path of the local git repo to fetch from" + method_option "branch", :type => :string, :default => nil, :banner => + "The git branch to checkout" + method_option "ref", :type => :string, :default => nil, :banner => + "The git revision to check out" + def install(*plugins) + Bundler::Plugin.install(plugins, options) + end + + desc "uninstall PLUGINS", "Uninstall the plugins" + long_desc <<-D + Uninstall given list of plugins. To uninstall all the plugins, use -all option. + D + method_option "all", :type => :boolean, :default => nil, :banner => + "Uninstall all the installed plugins. If no plugin is installed, then it does nothing." + def uninstall(*plugins) + Bundler::Plugin.uninstall(plugins, options) + end + + desc "list", "List the installed plugins and available commands" + def list + Bundler::Plugin.list + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/pristine.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/pristine.rb new file mode 100644 index 0000000..d6654f8 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/pristine.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Pristine + def initialize(gems) + @gems = gems + end + + def run + CLI::Common.ensure_all_gems_in_lockfile!(@gems) + definition = Bundler.definition + definition.validate_runtime! + installer = Bundler::Installer.new(Bundler.root, definition) + + Bundler.load.specs.each do |spec| + next if spec.name == "bundler" # Source::Rubygems doesn't install bundler + next if !@gems.empty? && !@gems.include?(spec.name) + + gem_name = "#{spec.name} (#{spec.version}#{spec.git_version})" + gem_name += " (#{spec.platform})" if !spec.platform.nil? && spec.platform != Gem::Platform::RUBY + + case source = spec.source + when Source::Rubygems + cached_gem = spec.cache_file + unless File.exist?(cached_gem) + Bundler.ui.error("Failed to pristine #{gem_name}. Cached gem #{cached_gem} does not exist.") + next + end + + FileUtils.rm_rf spec.full_gem_path + when Source::Git + if source.local? + Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is locally overridden.") + next + end + + source.remote! + if extension_cache_path = source.extension_cache_path(spec) + FileUtils.rm_rf extension_cache_path + end + FileUtils.rm_rf spec.extension_dir + FileUtils.rm_rf spec.full_gem_path + else + Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.") + next + end + + Bundler::GemInstaller.new(spec, installer, false, 0, true).install_from_spec + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/remove.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/remove.rb new file mode 100644 index 0000000..44a4d89 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/remove.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Remove + def initialize(gems, options) + @gems = gems + @options = options + end + + def run + raise InvalidOption, "Please specify gems to remove." if @gems.empty? + + Injector.remove(@gems, {}) + Installer.install(Bundler.root, Bundler.definition) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/show.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/show.rb new file mode 100644 index 0000000..2df13db --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/show.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Show + attr_reader :options, :gem_name, :latest_specs + def initialize(options, gem_name) + @options = options + @gem_name = gem_name + @verbose = options[:verbose] || options[:outdated] + @latest_specs = fetch_latest_specs if @verbose + end + + def run + Bundler.ui.silence do + Bundler.definition.validate_runtime! + Bundler.load.lock + end + + if gem_name + if gem_name == "bundler" + path = File.expand_path("../../..", __dir__) + else + spec = Bundler::CLI::Common.select_spec(gem_name, :regex_match) + return unless spec + path = spec.full_gem_path + unless File.directory?(path) + return Bundler.ui.warn "The gem #{gem_name} has been deleted. It was installed at: #{path}" + end + end + return Bundler.ui.info(path) + end + + if options[:paths] + Bundler.load.specs.sort_by(&:name).map do |s| + Bundler.ui.info s.full_gem_path + end + else + Bundler.ui.info "Gems included by the bundle:" + Bundler.load.specs.sort_by(&:name).each do |s| + desc = " * #{s.name} (#{s.version}#{s.git_version})" + if @verbose + latest = latest_specs.find {|l| l.name == s.name } + Bundler.ui.info <<-END.gsub(/^ +/, "") + #{desc} + \tSummary: #{s.summary || "No description available."} + \tHomepage: #{s.homepage || "No website available."} + \tStatus: #{outdated?(s, latest) ? "Outdated - #{s.version} < #{latest.version}" : "Up to date"} + END + else + Bundler.ui.info desc + end + end + end + end + + private + + def fetch_latest_specs + definition = Bundler.definition(true) + if options[:outdated] + Bundler.ui.info "Fetching remote specs for outdated check...\n\n" + Bundler.ui.silence { definition.resolve_remotely! } + else + definition.resolve_with_cache! + end + Bundler.reset! + definition.specs + end + + def outdated?(current, latest) + return false unless latest + Gem::Version.new(current.version) < Gem::Version.new(latest.version) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/update.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/update.rb new file mode 100644 index 0000000..b491826 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/update.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Update + attr_reader :options, :gems + def initialize(options, gems) + @options = options + @gems = gems + end + + def run + Bundler.ui.level = "warn" if options[:quiet] + + update_bundler = options[:bundler] + + Bundler.self_manager.update_bundler_and_restart_with_it_if_needed(update_bundler) if update_bundler + + Plugin.gemfile_install(Bundler.default_gemfile) if Bundler.feature_flag.plugins? + + sources = Array(options[:source]) + groups = Array(options[:group]).map(&:to_sym) + + full_update = gems.empty? && sources.empty? && groups.empty? && !options[:ruby] && !update_bundler + + if full_update && !options[:all] + if Bundler.feature_flag.update_requires_all_flag? + raise InvalidOption, "To update everything, pass the `--all` flag." + end + SharedHelpers.major_deprecation 3, "Pass --all to `bundle update` to update everything" + elsif !full_update && options[:all] + raise InvalidOption, "Cannot specify --all along with specific options." + end + + conservative = options[:conservative] + + if full_update + if conservative + Bundler.definition(:conservative => conservative) + else + Bundler.definition(true) + end + else + unless Bundler.default_lockfile.exist? + raise GemfileLockNotFound, "This Bundle hasn't been installed yet. " \ + "Run `bundle install` to update and install the bundled gems." + end + Bundler::CLI::Common.ensure_all_gems_in_lockfile!(gems) + + if groups.any? + deps = Bundler.definition.dependencies.select {|d| (d.groups & groups).any? } + gems.concat(deps.map(&:name)) + end + + Bundler.definition(:gems => gems, :sources => sources, :ruby => options[:ruby], + :conservative => conservative, + :bundler => update_bundler) + end + + Bundler::CLI::Common.configure_gem_version_promoter(Bundler.definition, options) + + Bundler::Fetcher.disable_endpoint = options["full-index"] + + opts = options.dup + opts["update"] = true + opts["local"] = options[:local] + + Bundler.settings.set_command_option_if_given :jobs, opts["jobs"] + + Bundler.definition.validate_runtime! + + if locked_gems = Bundler.definition.locked_gems + previous_locked_info = locked_gems.specs.reduce({}) do |h, s| + h[s.name] = { :spec => s, :version => s.version, :source => s.source.identifier } + h + end + end + + installer = Installer.install Bundler.root, Bundler.definition, opts + Bundler.load.cache if Bundler.app_cache.exist? + + if CLI::Common.clean_after_install? + require_relative "clean" + Bundler::CLI::Clean.new(options).run + end + + if locked_gems + gems.each do |name| + locked_info = previous_locked_info[name] + next unless locked_info + + locked_spec = locked_info[:spec] + new_spec = Bundler.definition.specs[name].first + unless new_spec + unless locked_spec.match_platform(Bundler.local_platform) + Bundler.ui.warn "Bundler attempted to update #{name} but it was not considered because it is for a different platform from the current one" + end + + next + end + + locked_source = locked_info[:source] + new_source = new_spec.source.identifier + next if locked_source != new_source + + new_version = new_spec.version + locked_version = locked_info[:version] + if new_version < locked_version + Bundler.ui.warn "Note: #{name} version regressed from #{locked_version} to #{new_version}" + elsif new_version == locked_version + Bundler.ui.warn "Bundler attempted to update #{name} but its version stayed the same" + end + end + end + + Bundler.ui.confirm "Bundle updated!" + Bundler::CLI::Common.output_without_groups_message(:update) + Bundler::CLI::Common.output_post_install_messages installer.post_install_messages + + Bundler::CLI::Common.output_fund_metadata_summary + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/cli/viz.rb b/games/FNaFB2/Ruby/stdlib/bundler/cli/viz.rb new file mode 100644 index 0000000..644f9b2 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/cli/viz.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Viz + attr_reader :options, :gem_name + def initialize(options) + @options = options + end + + def run + # make sure we get the right `graphviz`. There is also a `graphviz` + # gem we're not built to support + gem "ruby-graphviz" + require "graphviz" + + options[:without] = options[:without].join(":").tr(" ", ":").split(":") + output_file = File.expand_path(options[:file]) + + graph = Graph.new(Bundler.load, output_file, options[:version], options[:requirements], options[:format], options[:without]) + graph.viz + rescue LoadError => e + Bundler.ui.error e.inspect + Bundler.ui.warn "Make sure you have the graphviz ruby gem. You can install it with:" + Bundler.ui.warn "`gem install ruby-graphviz`" + rescue StandardError => e + raise unless e.message =~ /GraphViz not installed or dot not in PATH/ + Bundler.ui.error e.message + Bundler.ui.warn "Please install GraphViz. On a Mac with Homebrew, you can run `brew install graphviz`." + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/compact_index_client.rb b/games/FNaFB2/Ruby/stdlib/bundler/compact_index_client.rb new file mode 100644 index 0000000..127a50e --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/compact_index_client.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +require "pathname" +require "set" + +module Bundler + class CompactIndexClient + DEBUG_MUTEX = Thread::Mutex.new + def self.debug + return unless ENV["DEBUG_COMPACT_INDEX"] + DEBUG_MUTEX.synchronize { warn("[#{self}] #{yield}") } + end + + class Error < StandardError; end + + require_relative "compact_index_client/cache" + require_relative "compact_index_client/updater" + + attr_reader :directory + + def initialize(directory, fetcher) + @directory = Pathname.new(directory) + @updater = Updater.new(fetcher) + @cache = Cache.new(@directory) + @endpoints = Set.new + @info_checksums_by_name = {} + @parsed_checksums = false + @mutex = Thread::Mutex.new + end + + def execution_mode=(block) + Bundler::CompactIndexClient.debug { "execution_mode=" } + @endpoints = Set.new + + @execution_mode = block + end + + # @return [Lambda] A lambda that takes an array of inputs and a block, and + # maps the inputs with the block in parallel. + # + def execution_mode + @execution_mode || sequentially + end + + def sequential_execution_mode! + self.execution_mode = sequentially + end + + def sequentially + @sequentially ||= lambda do |inputs, &blk| + inputs.map(&blk) + end + end + + def names + Bundler::CompactIndexClient.debug { "/names" } + update(@cache.names_path, "names") + @cache.names + end + + def versions + Bundler::CompactIndexClient.debug { "/versions" } + update(@cache.versions_path, "versions") + versions, @info_checksums_by_name = @cache.versions + versions + end + + def dependencies(names) + Bundler::CompactIndexClient.debug { "dependencies(#{names})" } + execution_mode.call(names) do |name| + update_info(name) + @cache.dependencies(name).map {|d| d.unshift(name) } + end.flatten(1) + end + + def update_and_parse_checksums! + Bundler::CompactIndexClient.debug { "update_and_parse_checksums!" } + return @info_checksums_by_name if @parsed_checksums + update(@cache.versions_path, "versions") + @info_checksums_by_name = @cache.checksums + @parsed_checksums = true + end + + private + + def update(local_path, remote_path) + Bundler::CompactIndexClient.debug { "update(#{local_path}, #{remote_path})" } + unless synchronize { @endpoints.add?(remote_path) } + Bundler::CompactIndexClient.debug { "already fetched #{remote_path}" } + return + end + @updater.update(local_path, url(remote_path)) + end + + def update_info(name) + Bundler::CompactIndexClient.debug { "update_info(#{name})" } + path = @cache.info_path(name) + checksum = @updater.checksum_for_file(path) + unless existing = @info_checksums_by_name[name] + Bundler::CompactIndexClient.debug { "skipping updating info for #{name} since it is missing from versions" } + return + end + if checksum == existing + Bundler::CompactIndexClient.debug { "skipping updating info for #{name} since the versions checksum matches the local checksum" } + return + end + Bundler::CompactIndexClient.debug { "updating info for #{name} since the versions checksum #{existing} != the local checksum #{checksum}" } + update(path, "info/#{name}") + end + + def url(path) + path + end + + def synchronize + @mutex.synchronize { yield } + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/compact_index_client/cache.rb b/games/FNaFB2/Ruby/stdlib/bundler/compact_index_client/cache.rb new file mode 100644 index 0000000..2d83777 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/compact_index_client/cache.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +require_relative "gem_parser" + +module Bundler + class CompactIndexClient + class Cache + attr_reader :directory + + def initialize(directory) + @directory = Pathname.new(directory).expand_path + info_roots.each do |dir| + SharedHelpers.filesystem_access(dir) do + FileUtils.mkdir_p(dir) + end + end + end + + def names + lines(names_path) + end + + def names_path + directory.join("names") + end + + def versions + versions_by_name = Hash.new {|hash, key| hash[key] = [] } + info_checksums_by_name = {} + + lines(versions_path).each do |line| + name, versions_string, info_checksum = line.split(" ", 3) + info_checksums_by_name[name] = info_checksum || "" + versions_string.split(",").each do |version| + if version.start_with?("-") + version = version[1..-1].split("-", 2).unshift(name) + versions_by_name[name].delete(version) + else + version = version.split("-", 2).unshift(name) + versions_by_name[name] << version + end + end + end + + [versions_by_name, info_checksums_by_name] + end + + def versions_path + directory.join("versions") + end + + def checksums + checksums = {} + + lines(versions_path).each do |line| + name, _, checksum = line.split(" ", 3) + checksums[name] = checksum + end + + checksums + end + + def dependencies(name) + lines(info_path(name)).map do |line| + parse_gem(line) + end + end + + def info_path(name) + name = name.to_s + if name =~ /[^a-z0-9_-]/ + name += "-#{SharedHelpers.digest(:MD5).hexdigest(name).downcase}" + info_roots.last.join(name) + else + info_roots.first.join(name) + end + end + + private + + def lines(path) + return [] unless path.file? + lines = SharedHelpers.filesystem_access(path, :read, &:read).split("\n") + header = lines.index("---") + header ? lines[header + 1..-1] : lines + end + + def parse_gem(line) + @dependency_parser ||= GemParser.new + @dependency_parser.parse(line) + end + + def info_roots + [ + directory.join("info"), + directory.join("info-special-characters"), + ] + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/compact_index_client/gem_parser.rb b/games/FNaFB2/Ruby/stdlib/bundler/compact_index_client/gem_parser.rb new file mode 100644 index 0000000..e7bf4c6 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/compact_index_client/gem_parser.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Bundler + class CompactIndexClient + if defined?(Gem::Resolver::APISet::GemParser) + GemParser = Gem::Resolver::APISet::GemParser + else + class GemParser + def parse(line) + version_and_platform, rest = line.split(" ", 2) + version, platform = version_and_platform.split("-", 2) + dependencies, requirements = rest.split("|", 2).map {|s| s.split(",") } if rest + dependencies = dependencies ? dependencies.map {|d| parse_dependency(d) } : [] + requirements = requirements ? requirements.map {|d| parse_dependency(d) } : [] + [version, platform, dependencies, requirements] + end + + private + + def parse_dependency(string) + dependency = string.split(":") + dependency[-1] = dependency[-1].split("&") if dependency.size > 1 + dependency + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/compact_index_client/updater.rb b/games/FNaFB2/Ruby/stdlib/bundler/compact_index_client/updater.rb new file mode 100644 index 0000000..5b430df --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/compact_index_client/updater.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true + +require_relative "../vendored_fileutils" + +module Bundler + class CompactIndexClient + class Updater + class MisMatchedChecksumError < Error + def initialize(path, server_checksum, local_checksum) + @path = path + @server_checksum = server_checksum + @local_checksum = local_checksum + end + + def message + "The checksum of /#{@path} does not match the checksum provided by the server! Something is wrong " \ + "(local checksum is #{@local_checksum.inspect}, was expecting #{@server_checksum.inspect})." + end + end + + def initialize(fetcher) + @fetcher = fetcher + require_relative "../vendored_tmpdir" + end + + def update(local_path, remote_path, retrying = nil) + headers = {} + + Bundler::Dir.mktmpdir("bundler-compact-index-") do |local_temp_dir| + local_temp_path = Pathname.new(local_temp_dir).join(local_path.basename) + + # first try to fetch any new bytes on the existing file + if retrying.nil? && local_path.file? + copy_file local_path, local_temp_path + + headers["If-None-Match"] = etag_for(local_temp_path) + headers["Range"] = + if local_temp_path.size.nonzero? + # Subtract a byte to ensure the range won't be empty. + # Avoids 416 (Range Not Satisfiable) responses. + "bytes=#{local_temp_path.size - 1}-" + else + "bytes=#{local_temp_path.size}-" + end + end + + response = @fetcher.call(remote_path, headers) + return nil if response.is_a?(Net::HTTPNotModified) + + content = response.body + + etag = (response["ETag"] || "").gsub(%r{\AW/}, "") + correct_response = SharedHelpers.filesystem_access(local_temp_path) do + if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero? + local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) } + + etag_for(local_temp_path) == etag + else + local_temp_path.open("wb") {|f| f << content } + + etag.length.zero? || etag_for(local_temp_path) == etag + end + end + + if correct_response + SharedHelpers.filesystem_access(local_path) do + FileUtils.mv(local_temp_path, local_path) + end + return nil + end + + if retrying + raise MisMatchedChecksumError.new(remote_path, etag, etag_for(local_temp_path)) + end + + update(local_path, remote_path, :retrying) + end + rescue Zlib::GzipFile::Error + raise Bundler::HTTPError + end + + def etag_for(path) + sum = checksum_for_file(path) + sum ? %("#{sum}") : nil + end + + def slice_body(body, range) + body.byteslice(range) + end + + def checksum_for_file(path) + return nil unless path.file? + # This must use File.read instead of Digest.file().hexdigest + # because we need to preserve \n line endings on windows when calculating + # the checksum + SharedHelpers.filesystem_access(path, :read) do + SharedHelpers.digest(:MD5).hexdigest(File.read(path)) + end + end + + private + + def copy_file(source, dest) + SharedHelpers.filesystem_access(source, :read) do + File.open(source, "r") do |s| + SharedHelpers.filesystem_access(dest, :write) do + File.open(dest, "wb", s.stat.mode) do |f| + IO.copy_stream(s, f) + end + end + end + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/constants.rb b/games/FNaFB2/Ruby/stdlib/bundler/constants.rb new file mode 100644 index 0000000..2e4ebb3 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/constants.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Bundler + WINDOWS = RbConfig::CONFIG["host_os"] =~ /(msdos|mswin|djgpp|mingw)/ + FREEBSD = RbConfig::CONFIG["host_os"] =~ /bsd/ + NULL = WINDOWS ? "NUL" : "/dev/null" +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/current_ruby.rb b/games/FNaFB2/Ruby/stdlib/bundler/current_ruby.rb new file mode 100644 index 0000000..f9987c4 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/current_ruby.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +module Bundler + # Returns current version of Ruby + # + # @return [CurrentRuby] Current version of Ruby + def self.current_ruby + @current_ruby ||= CurrentRuby.new + end + + class CurrentRuby + KNOWN_MINOR_VERSIONS = %w[ + 1.8 + 1.9 + 2.0 + 2.1 + 2.2 + 2.3 + 2.4 + 2.5 + 2.6 + 2.7 + 3.0 + 3.1 + ].freeze + + KNOWN_MAJOR_VERSIONS = KNOWN_MINOR_VERSIONS.map {|v| v.split(".", 2).first }.uniq.freeze + + KNOWN_PLATFORMS = %w[ + jruby + maglev + mingw + mri + mswin + mswin64 + rbx + ruby + truffleruby + windows + x64_mingw + ].freeze + + def ruby? + return true if Bundler::GemHelpers.generic_local_platform == Gem::Platform::RUBY + + !windows? && (RUBY_ENGINE == "ruby" || RUBY_ENGINE == "rbx" || RUBY_ENGINE == "maglev" || RUBY_ENGINE == "truffleruby") + end + + def mri? + !windows? && RUBY_ENGINE == "ruby" + end + + def rbx? + ruby? && RUBY_ENGINE == "rbx" + end + + def jruby? + RUBY_ENGINE == "jruby" + end + + def maglev? + RUBY_ENGINE == "maglev" + end + + def truffleruby? + RUBY_ENGINE == "truffleruby" + end + + def windows? + Gem.win_platform? + end + + def mswin? + # For backwards compatibility + windows? + + # TODO: This should correctly be: + # windows? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin32" && Bundler.local_platform.cpu == "x86" + end + + def mswin64? + windows? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin64" && Bundler.local_platform.cpu == "x64" + end + + def mingw? + windows? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu != "x64" + end + + def x64_mingw? + Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os.start_with?("mingw") && Bundler.local_platform.cpu == "x64" + end + + (KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version| + trimmed_version = version.tr(".", "") + define_method(:"on_#{trimmed_version}?") do + RUBY_VERSION.start_with?("#{version}.") + end + + KNOWN_PLATFORMS.each do |platform| + define_method(:"#{platform}_#{trimmed_version}?") do + send(:"#{platform}?") && send(:"on_#{trimmed_version}?") + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/definition.rb b/games/FNaFB2/Ruby/stdlib/bundler/definition.rb new file mode 100644 index 0000000..3836841 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/definition.rb @@ -0,0 +1,875 @@ +# frozen_string_literal: true + +require_relative "lockfile_parser" + +module Bundler + class Definition + include GemHelpers + + class << self + # Do not create or modify a lockfile (Makes #lock a noop) + attr_accessor :no_lock + end + + attr_reader( + :dependencies, + :locked_deps, + :locked_gems, + :platforms, + :requires, + :ruby_version, + :lockfile, + :gemfiles + ) + + # Given a gemfile and lockfile creates a Bundler definition + # + # @param gemfile [Pathname] Path to Gemfile + # @param lockfile [Pathname,nil] Path to Gemfile.lock + # @param unlock [Hash, Boolean, nil] Gems that have been requested + # to be updated or true if all gems should be updated + # @return [Bundler::Definition] + def self.build(gemfile, lockfile, unlock) + unlock ||= {} + gemfile = Pathname.new(gemfile).expand_path + + raise GemfileNotFound, "#{gemfile} not found" unless gemfile.file? + + Dsl.evaluate(gemfile, lockfile, unlock) + end + + # + # How does the new system work? + # + # * Load information from Gemfile and Lockfile + # * Invalidate stale locked specs + # * All specs from stale source are stale + # * All specs that are reachable only through a stale + # dependency are stale. + # * If all fresh dependencies are satisfied by the locked + # specs, then we can try to resolve locally. + # + # @param lockfile [Pathname] Path to Gemfile.lock + # @param dependencies [Array(Bundler::Dependency)] array of dependencies from Gemfile + # @param sources [Bundler::SourceList] + # @param unlock [Hash, Boolean, nil] Gems that have been requested + # to be updated or true if all gems should be updated + # @param ruby_version [Bundler::RubyVersion, nil] Requested Ruby Version + # @param optional_groups [Array(String)] A list of optional groups + def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, optional_groups = [], gemfiles = []) + if [true, false].include?(unlock) + @unlocking_bundler = false + @unlocking = unlock + else + @unlocking_bundler = unlock.delete(:bundler) + @unlocking = unlock.any? {|_k, v| !Array(v).empty? } + end + + @dependencies = dependencies + @sources = sources + @unlock = unlock + @optional_groups = optional_groups + @remote = false + @prefer_local = false + @specs = nil + @ruby_version = ruby_version + @gemfiles = gemfiles + + @lockfile = lockfile + @lockfile_contents = String.new + @locked_bundler_version = nil + @locked_ruby_version = nil + @new_platform = nil + + if lockfile && File.exist?(lockfile) + @lockfile_contents = Bundler.read_file(lockfile) + @locked_gems = LockfileParser.new(@lockfile_contents) + @locked_platforms = @locked_gems.platforms + @platforms = @locked_platforms.dup + @locked_bundler_version = @locked_gems.bundler_version + @locked_ruby_version = @locked_gems.ruby_version + @originally_locked_specs = SpecSet.new(@locked_gems.specs) + + if unlock != true + @locked_deps = @locked_gems.dependencies + @locked_specs = @originally_locked_specs + @locked_sources = @locked_gems.sources + else + @unlock = {} + @locked_deps = {} + @locked_specs = SpecSet.new([]) + @locked_sources = [] + end + else + @unlock = {} + @platforms = [] + @locked_gems = nil + @locked_deps = {} + @locked_specs = SpecSet.new([]) + @originally_locked_specs = @locked_specs + @locked_sources = [] + @locked_platforms = [] + end + + locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) } + @multisource_allowed = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes? && Bundler.frozen_bundle? + + if @multisource_allowed + unless sources.aggregate_global_source? + msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure." + + Bundler::SharedHelpers.major_deprecation 2, msg + end + + @sources.merged_gem_lockfile_sections!(locked_gem_sources.first) + end + + @unlock[:sources] ||= [] + @unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object + @ruby_version.diff(locked_ruby_version_object) + end + @unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version) + + add_current_platform unless current_ruby_platform_locked? || Bundler.frozen_bundle? + + converge_path_sources_to_gemspec_sources + @path_changes = converge_paths + @source_changes = converge_sources + + if @unlock[:conservative] + @unlock[:gems] ||= @dependencies.map(&:name) + else + eager_unlock = (@unlock[:gems] || []).map {|name| Dependency.new(name, ">= 0") } + @unlock[:gems] = @locked_specs.for(eager_unlock, false, platforms).map(&:name).uniq + end + + @dependency_changes = converge_dependencies + @local_changes = converge_locals + + @requires = compute_requires + end + + def gem_version_promoter + @gem_version_promoter ||= GemVersionPromoter.new(@originally_locked_specs, @unlock[:gems]) + end + + def resolve_only_locally! + @remote = false + sources.local_only! + resolve + end + + def resolve_prefering_local! + @prefer_local = true + @remote = true + sources.remote! + resolve + end + + def resolve_with_cache! + sources.cached! + resolve + end + + def resolve_remotely! + @remote = true + sources.remote! + resolve + end + + # For given dependency list returns a SpecSet with Gemspec of all the required + # dependencies. + # 1. The method first resolves the dependencies specified in Gemfile + # 2. After that it tries and fetches gemspec of resolved dependencies + # + # @return [Bundler::SpecSet] + def specs + @specs ||= materialize(requested_dependencies) + end + + def new_specs + specs - @locked_specs + end + + def removed_specs + @locked_specs - specs + end + + def missing_specs + resolve.materialize(requested_dependencies).missing_specs + end + + def missing_specs? + missing = missing_specs + return false if missing.empty? + Bundler.ui.debug "The definition is missing #{missing.map(&:full_name)}" + true + rescue BundlerError => e + @resolve = nil + @resolver = nil + @specs = nil + @gem_version_promoter = nil + + Bundler.ui.debug "The definition is missing dependencies, failed to resolve & materialize locally (#{e})" + true + end + + def requested_specs + specs_for(requested_groups) + end + + def requested_dependencies + dependencies_for(requested_groups) + end + + def current_dependencies + dependencies.select do |d| + d.should_include? && !d.gem_platforms([generic_local_platform]).empty? + end + end + + def locked_dependencies + @locked_deps.values + end + + def new_deps + @new_deps ||= @dependencies - locked_dependencies + end + + def deleted_deps + @deleted_deps ||= locked_dependencies - @dependencies + end + + def specs_for(groups) + return specs if groups.empty? + deps = dependencies_for(groups) + materialize(deps) + end + + def dependencies_for(groups) + groups.map!(&:to_sym) + current_dependencies.reject do |d| + (d.groups & groups).empty? + end + end + + # Resolve all the dependencies specified in Gemfile. It ensures that + # dependencies that have been already resolved via locked file and are fresh + # are reused when resolving dependencies + # + # @return [SpecSet] resolved dependencies + def resolve + @resolve ||= if Bundler.frozen_bundle? + Bundler.ui.debug "Frozen, using resolution from the lockfile" + @locked_specs + elsif !unlocking? && nothing_changed? + if deleted_deps.any? + Bundler.ui.debug("Some dependencies were deleted, using a subset of the resolution from the lockfile") + SpecSet.new(filter_specs(@locked_specs, @dependencies - deleted_deps)) + else + Bundler.ui.debug("Found no changes, using resolution from the lockfile") + if @locked_gems.may_include_redundant_platform_specific_gems? + SpecSet.new(filter_specs(@locked_specs, @dependencies)) + else + @locked_specs + end + end + else + Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}") + resolver.start(expanded_dependencies) + end + end + + def spec_git_paths + sources.git_sources.map {|s| File.realpath(s.path) if File.exist?(s.path) }.compact + end + + def groups + dependencies.map(&:groups).flatten.uniq + end + + def lock(file, preserve_unknown_sections = false) + return if Definition.no_lock + + contents = to_lock + + # Convert to \r\n if the existing lock has them + # i.e., Windows with `git config core.autocrlf=true` + contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match("\r\n") + + if @locked_bundler_version + locked_major = @locked_bundler_version.segments.first + current_major = Gem::Version.create(Bundler::VERSION).segments.first + + updating_major = locked_major < current_major + end + + preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler)) + + return if file && File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections) + + if Bundler.frozen_bundle? + Bundler.ui.error "Cannot write a changed lockfile while frozen." + return + end + + SharedHelpers.filesystem_access(file) do |p| + File.open(p, "wb") {|f| f.puts(contents) } + end + end + + def locked_ruby_version + return unless ruby_version + if @unlock[:ruby] || !@locked_ruby_version + Bundler::RubyVersion.system + else + @locked_ruby_version + end + end + + def locked_ruby_version_object + return unless @locked_ruby_version + @locked_ruby_version_object ||= begin + unless version = RubyVersion.from_string(@locked_ruby_version) + raise LockfileError, "The Ruby version #{@locked_ruby_version} from " \ + "#{@lockfile} could not be parsed. " \ + "Try running bundle update --ruby to resolve this." + end + version + end + end + + def to_lock + require_relative "lockfile_generator" + LockfileGenerator.generate(self) + end + + def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false) + msg = String.new + msg << "You are trying to install in deployment mode after changing\n" \ + "your Gemfile. Run `bundle install` elsewhere and add the\n" \ + "updated #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} to version control." + + unless explicit_flag + suggested_command = if Bundler.settings.locations("frozen").keys.&([:global, :local]).any? + "bundle config unset frozen" + elsif Bundler.settings.locations("deployment").keys.&([:global, :local]).any? + "bundle config unset deployment" + end + msg << "\n\nIf this is a development machine, remove the #{Bundler.default_gemfile} " \ + "freeze \nby running `#{suggested_command}`." if suggested_command + end + + added = [] + deleted = [] + changed = [] + + new_platforms = @platforms - @locked_platforms + deleted_platforms = @locked_platforms - @platforms + added.concat new_platforms.map {|p| "* platform: #{p}" } + deleted.concat deleted_platforms.map {|p| "* platform: #{p}" } + + added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any? + deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any? + + both_sources = Hash.new {|h, k| h[k] = [] } + @dependencies.each {|d| both_sources[d.name][0] = d } + + locked_dependencies.each do |d| + next if !Bundler.feature_flag.bundler_3_mode? && @locked_specs[d.name].empty? + + both_sources[d.name][1] = d + end + + both_sources.each do |name, (dep, lock_dep)| + next if dep.nil? || lock_dep.nil? + + gemfile_source = dep.source || sources.default_source + lock_source = lock_dep.source || sources.default_source + next if lock_source.include?(gemfile_source) + + gemfile_source_name = dep.source ? gemfile_source.identifier : "no specified source" + lockfile_source_name = lock_dep.source ? lock_source.identifier : "no specified source" + changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`" + end + + reason = change_reason + msg << "\n\n#{reason.split(", ").map(&:capitalize).join("\n")}" unless reason.strip.empty? + msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any? + msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any? + msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any? + msg << "\n" + + raise ProductionError, msg if added.any? || deleted.any? || changed.any? || !nothing_changed? + end + + def validate_runtime! + validate_ruby! + validate_platforms! + end + + def validate_ruby! + return unless ruby_version + + if diff = ruby_version.diff(Bundler::RubyVersion.system) + problem, expected, actual = diff + + msg = case problem + when :engine + "Your Ruby engine is #{actual}, but your Gemfile specified #{expected}" + when :version + "Your Ruby version is #{actual}, but your Gemfile specified #{expected}" + when :engine_version + "Your #{Bundler::RubyVersion.system.engine} version is #{actual}, but your Gemfile specified #{ruby_version.engine} #{expected}" + when :patchlevel + if !expected.is_a?(String) + "The Ruby patchlevel in your Gemfile must be a string" + else + "Your Ruby patchlevel is #{actual}, but your Gemfile specified #{expected}" + end + end + + raise RubyVersionMismatch, msg + end + end + + def validate_platforms! + return if current_platform_locked? + + raise ProductionError, "Your bundle only supports platforms #{@platforms.map(&:to_s)} " \ + "but your local platform is #{Bundler.local_platform}. " \ + "Add the current platform to the lockfile with\n`bundle lock --add-platform #{Bundler.local_platform}` and try again." + end + + def add_platform(platform) + @new_platform ||= !@platforms.include?(platform) + @platforms |= [platform] + end + + def remove_platform(platform) + return if @platforms.delete(Gem::Platform.new(platform)) + raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}" + end + + def most_specific_locked_platform + @platforms.min_by do |bundle_platform| + platform_specificity_match(bundle_platform, local_platform) + end + end + + attr_reader :sources + private :sources + + def nothing_changed? + !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes + end + + def unlocking? + @unlocking + end + + private + + def resolver + @resolver ||= begin + last_resolve = converge_locked_specs + remove_ruby_from_platforms_if_necessary!(current_dependencies) + Resolver.new(source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve(last_resolve), platforms) + end + end + + def expanded_dependencies + @expanded_dependencies ||= dependencies + metadata_dependencies + end + + def filter_specs(specs, deps) + SpecSet.new(specs).for(deps, false, platforms) + end + + def materialize(dependencies) + specs = resolve.materialize(dependencies) + missing_specs = specs.missing_specs + + if missing_specs.any? + missing_specs.each do |s| + locked_gem = @locked_specs[s.name].last + next if locked_gem.nil? || locked_gem.version != s.version || !@remote + raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \ + "no longer be found in that source. That means the author of #{locked_gem} has removed it. " \ + "You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \ + "removed in order to install." + end + + missing_specs_list = missing_specs.group_by(&:source).map do |source, missing_specs_for_source| + "#{missing_specs_for_source.map(&:full_name).join(", ")} in #{source}" + end + + raise GemNotFound, "Could not find #{missing_specs_list.join(" nor ")}" + end + + loop do + incomplete_specs = specs.incomplete_specs + break if incomplete_specs.empty? + + Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies") + @resolve = resolver.start(expanded_dependencies, :exclude_specs => incomplete_specs) + specs = resolve.materialize(dependencies) + end + + bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last + specs["bundler"] = bundler + + specs + end + + def precompute_source_requirements_for_indirect_dependencies? + @remote && sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source? + end + + def pin_locally_available_names(source_requirements) + source_requirements.each_with_object({}) do |(name, original_source), new_source_requirements| + local_source = original_source.dup + local_source.local_only! + + new_source_requirements[name] = if local_source.specs.search(name).any? + local_source + else + original_source + end + end + end + + def current_ruby_platform_locked? + return false unless generic_local_platform == Gem::Platform::RUBY + return false if Bundler.settings[:force_ruby_platform] && !@platforms.include?(Gem::Platform::RUBY) + + current_platform_locked? + end + + def current_platform_locked? + @platforms.any? do |bundle_platform| + MatchPlatform.platforms_match?(bundle_platform, Bundler.local_platform) + end + end + + def add_current_platform + add_platform(local_platform) + end + + def change_reason + if unlocking? + unlock_reason = @unlock.reject {|_k, v| Array(v).empty? }.map do |k, v| + if v == true + k.to_s + else + v = Array(v) + "#{k}: (#{v.join(", ")})" + end + end.join(", ") + return "bundler is unlocking #{unlock_reason}" + end + [ + [@source_changes, "the list of sources changed"], + [@dependency_changes, "the dependencies in your gemfile changed"], + [@new_platform, "you added a new platform to your gemfile"], + [@path_changes, "the gemspecs for path gems changed"], + [@local_changes, "the gemspecs for git local gems changed"], + ].select(&:first).map(&:last).join(", ") + end + + def pretty_dep(dep) + SharedHelpers.pretty_dependency(dep) + end + + # Check if the specs of the given source changed + # according to the locked source. + def specs_changed?(source) + locked = @locked_sources.find {|s| s == source } + + !locked || dependencies_for_source_changed?(source, locked) || specs_for_source_changed?(source) + end + + def dependencies_for_source_changed?(source, locked_source = source) + deps_for_source = @dependencies.select {|s| s.source == source } + locked_deps_for_source = locked_dependencies.select {|dep| dep.source == locked_source } + + deps_for_source.uniq.sort != locked_deps_for_source.sort + end + + def specs_for_source_changed?(source) + locked_index = Index.new + locked_index.use(@locked_specs.select {|s| source.can_lock?(s) }) + + # order here matters, since Index#== is checking source.specs.include?(locked_index) + locked_index != source.specs + rescue PathError, GitError => e + Bundler.ui.debug "Assuming that #{source} has not changed since fetching its specs errored (#{e})" + false + end + + # Get all locals and override their matching sources. + # Return true if any of the locals changed (for example, + # they point to a new revision) or depend on new specs. + def converge_locals + locals = [] + + Bundler.settings.local_overrides.map do |k, v| + spec = @dependencies.find {|s| s.name == k } + source = spec && spec.source + if source && source.respond_to?(:local_override!) + source.unlock! if @unlock[:gems].include?(spec.name) + locals << [source, source.local_override!(v)] + end + end + + sources_with_changes = locals.select do |source, changed| + changed || specs_changed?(source) + end.map(&:first) + !sources_with_changes.each {|source| @unlock[:sources] << source.name }.empty? + end + + def converge_paths + sources.path_sources.any? do |source| + specs_changed?(source) + end + end + + def converge_path_source_to_gemspec_source(source) + return source unless source.instance_of?(Source::Path) + gemspec_source = sources.path_sources.find {|s| s.is_a?(Source::Gemspec) && s.as_path_source == source } + gemspec_source || source + end + + def converge_path_sources_to_gemspec_sources + @locked_sources.map! do |source| + converge_path_source_to_gemspec_source(source) + end + @locked_specs.each do |spec| + spec.source &&= converge_path_source_to_gemspec_source(spec.source) + end + @locked_deps.each do |_, dep| + dep.source &&= converge_path_source_to_gemspec_source(dep.source) + end + end + + def converge_sources + # Replace the sources from the Gemfile with the sources from the Gemfile.lock, + # if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent + # source in the Gemfile.lock, use the one from the Gemfile. + changes = sources.replace_sources!(@locked_sources) + + sources.all_sources.each do |source| + # If the source is unlockable and the current command allows an unlock of + # the source (for example, you are doing a `bundle update ` of a git-pinned + # gem), unlock it. For git sources, this means to unlock the revision, which + # will cause the `ref` used to be the most recent for the branch (or master) if + # an explicit `ref` is not used. + if source.respond_to?(:unlock!) && @unlock[:sources].include?(source.name) + source.unlock! + changes = true + end + end + + changes + end + + def converge_dependencies + changes = false + + @dependencies.each do |dep| + if dep.source + dep.source = sources.get(dep.source) + end + + unless locked_dep = @locked_deps[dep.name] + changes = true + next + end + + # Gem::Dependency#== matches Gem::Dependency#type. As the lockfile + # doesn't carry a notion of the dependency type, if you use + # add_development_dependency in a gemspec that's loaded with the gemspec + # directive, the lockfile dependencies and resolved dependencies end up + # with a mismatch on #type. Work around that by setting the type on the + # dep from the lockfile. + locked_dep.instance_variable_set(:@type, dep.type) + + # We already know the name matches from the hash lookup + # so we only need to check the requirement now + changes ||= dep.requirement != locked_dep.requirement + end + + changes + end + + # Remove elements from the locked specs that are expired. This will most + # commonly happen if the Gemfile has changed since the lockfile was last + # generated + def converge_locked_specs + converged = converge_specs(@locked_specs) + + resolve = SpecSet.new(converged.reject {|s| @unlock[:gems].include?(s.name) }) + + diff = nil + + # Now, we unlock any sources that do not have anymore gems pinned to it + sources.all_sources.each do |source| + next unless source.respond_to?(:unlock!) + + unless resolve.any? {|s| s.source == source } + diff ||= @locked_specs.to_a - resolve.to_a + source.unlock! if diff.any? {|s| s.source == source } + end + end + + resolve + end + + def converge_specs(specs) + converged = [] + + deps = @dependencies.select do |dep| + specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) } + end + + @specs_that_changed_sources = [] + + specs.each do |s| + dep = @dependencies.find {|d| s.satisfies?(d) } + + # Replace the locked dependency's source with the equivalent source from the Gemfile + s.source = if dep && dep.source + gemfile_source = dep.source + lockfile_source = s.source + + @specs_that_changed_sources << s if gemfile_source != lockfile_source + + gemfile_source + else + sources.get_with_fallback(s.source) + end + + next if @unlock[:sources].include?(s.source.name) + + # Path sources have special logic + if s.source.instance_of?(Source::Path) || s.source.instance_of?(Source::Gemspec) + new_specs = begin + s.source.specs + rescue PathError, GitError + # if we won't need the source (according to the lockfile), + # don't error if the path/git source isn't available + next if specs. + for(requested_dependencies, false). + none? {|locked_spec| locked_spec.source == s.source } + + raise + end + + new_spec = new_specs[s].first + + # If the spec is no longer in the path source, unlock it. This + # commonly happens if the version changed in the gemspec + next unless new_spec + + s.dependencies.replace(new_spec.dependencies) + end + + if dep.nil? && requested_dependencies.find {|d| s.name == d.name } + @unlock[:gems] << s.name + else + converged << s + end + end + + filter_specs(converged, deps) + end + + def metadata_dependencies + @metadata_dependencies ||= [ + Dependency.new("Ruby\0", Gem.ruby_version), + Dependency.new("RubyGems\0", Gem::VERSION), + ] + end + + def source_requirements + # Record the specs available in each gem's source, so that those + # specs will be available later when the resolver knows where to + # look for that gemspec (or its dependencies) + source_requirements = if precompute_source_requirements_for_indirect_dependencies? + all_requirements = source_map.all_requirements + all_requirements = pin_locally_available_names(all_requirements) if @prefer_local + { :default => sources.default_source }.merge(all_requirements) + else + { :default => Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements) + end + source_requirements.merge!(source_map.locked_requirements) unless @remote + metadata_dependencies.each do |dep| + source_requirements[dep.name] = sources.metadata_source + end + source_requirements[:default_bundler] = source_requirements["bundler"] || sources.default_source + source_requirements["bundler"] = sources.metadata_source # needs to come last to override + verify_changed_sources! + source_requirements + end + + def verify_changed_sources! + @specs_that_changed_sources.each do |s| + if s.source.specs.search(s.name).empty? + raise GemNotFound, "Could not find gem '#{s.name}' in #{s.source}" + end + end + end + + def requested_groups + values = groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with] + values &= Bundler.settings[:only] unless Bundler.settings[:only].empty? + values + end + + def lockfiles_equal?(current, proposed, preserve_unknown_sections) + if preserve_unknown_sections + sections_to_ignore = LockfileParser.sections_to_ignore(@locked_bundler_version) + sections_to_ignore += LockfileParser.unknown_sections_in_lockfile(current) + sections_to_ignore += LockfileParser::ENVIRONMENT_VERSION_SECTIONS + pattern = /#{Regexp.union(sections_to_ignore)}\n(\s{2,}.*\n)+/ + whitespace_cleanup = /\n{2,}/ + current = current.gsub(pattern, "\n").gsub(whitespace_cleanup, "\n\n").strip + proposed = proposed.gsub(pattern, "\n").gsub(whitespace_cleanup, "\n\n").strip + end + current == proposed + end + + def compute_requires + dependencies.reduce({}) do |requires, dep| + next requires unless dep.should_include? + requires[dep.name] = Array(dep.autorequire || dep.name).map do |file| + # Allow `require: true` as an alias for `require: ` + file == true ? dep.name : file + end + requires + end + end + + def additional_base_requirements_for_resolve(last_resolve) + return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources) + converge_specs(@originally_locked_specs - last_resolve).map do |locked_spec| + Dependency.new(locked_spec.name, ">= #{locked_spec.version}") + end.uniq + end + + def remove_ruby_from_platforms_if_necessary!(dependencies) + return if Bundler.frozen_bundle? || + Bundler.local_platform == Gem::Platform::RUBY || + !platforms.include?(Gem::Platform::RUBY) || + (@new_platform && platforms.last == Gem::Platform::RUBY) || + !@originally_locked_specs.incomplete_ruby_specs?(dependencies) + + remove_platform(Gem::Platform::RUBY) + add_current_platform + end + + def source_map + @source_map ||= SourceMap.new(sources, dependencies, @locked_specs) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/dependency.rb b/games/FNaFB2/Ruby/stdlib/bundler/dependency.rb new file mode 100644 index 0000000..01ae61b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/dependency.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +require "rubygems/dependency" +require_relative "shared_helpers" +require_relative "rubygems_ext" + +module Bundler + class Dependency < Gem::Dependency + attr_reader :autorequire + attr_reader :groups, :platforms, :gemfile, :path, :git, :github, :branch, :ref, :force_ruby_platform + + ALL_RUBY_VERSIONS = ((18..27).to_a + (30..31).to_a).freeze + PLATFORM_MAP = { + :ruby => [Gem::Platform::RUBY, ALL_RUBY_VERSIONS], + :mri => [Gem::Platform::RUBY, ALL_RUBY_VERSIONS], + :rbx => [Gem::Platform::RUBY], + :truffleruby => [Gem::Platform::RUBY], + :jruby => [Gem::Platform::JAVA, [18, 19]], + :windows => [Gem::Platform::WINDOWS, ALL_RUBY_VERSIONS], + :mswin => [Gem::Platform::MSWIN, ALL_RUBY_VERSIONS], + :mswin64 => [Gem::Platform::MSWIN64, ALL_RUBY_VERSIONS - [18]], + :mingw => [Gem::Platform::MINGW, ALL_RUBY_VERSIONS], + :x64_mingw => [Gem::Platform::X64_MINGW, ALL_RUBY_VERSIONS - [18, 19]], + }.each_with_object({}) do |(platform, spec), hash| + hash[platform] = spec[0] + spec[1]&.each {|version| hash[:"#{platform}_#{version}"] = spec[0] } + end.freeze + + def initialize(name, version, options = {}, &blk) + type = options["type"] || :runtime + super(name, version, type) + + @autorequire = nil + @groups = Array(options["group"] || :default).map(&:to_sym) + @source = options["source"] + @path = options["path"] + @git = options["git"] + @github = options["github"] + @branch = options["branch"] + @ref = options["ref"] + @platforms = Array(options["platforms"]) + @env = options["env"] + @should_include = options.fetch("should_include", true) + @gemfile = options["gemfile"] + @force_ruby_platform = options["force_ruby_platform"] + + @autorequire = Array(options["require"] || []) if options.key?("require") + end + + # Returns the platforms this dependency is valid for, in the same order as + # passed in the `valid_platforms` parameter + def gem_platforms(valid_platforms) + return valid_platforms if @platforms.empty? + + valid_platforms.select {|p| expanded_platforms.include?(GemHelpers.generic(p)) } + end + + def expanded_platforms + @expanded_platforms ||= @platforms.map {|pl| PLATFORM_MAP[pl] }.compact.flatten.uniq + end + + def should_include? + @should_include && current_env? && current_platform? + end + + def current_env? + return true unless @env + if @env.is_a?(Hash) + @env.all? do |key, val| + ENV[key.to_s] && (val.is_a?(String) ? ENV[key.to_s] == val : ENV[key.to_s] =~ val) + end + else + ENV[@env.to_s] + end + end + + def current_platform? + return true if @platforms.empty? + @platforms.any? do |p| + Bundler.current_ruby.send("#{p}?") + end + end + + def to_lock + out = super + out << "!" if source + out + end + + def specific? + super + rescue NoMethodError + requirement != ">= 0" + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/deployment.rb b/games/FNaFB2/Ruby/stdlib/bundler/deployment.rb new file mode 100644 index 0000000..b432ae6 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/deployment.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require_relative "shared_helpers" +Bundler::SharedHelpers.major_deprecation 2, "Bundler no longer integrates with " \ + "Capistrano, but Capistrano provides its own integration with " \ + "Bundler via the capistrano-bundler gem. Use it instead." + +module Bundler + class Deployment + def self.define_task(context, task_method = :task, opts = {}) + if defined?(Capistrano) && context.is_a?(Capistrano::Configuration) + context_name = "capistrano" + role_default = "{:except => {:no_release => true}}" + error_type = ::Capistrano::CommandError + else + context_name = "vlad" + role_default = "[:app]" + error_type = ::Rake::CommandFailedError + end + + roles = context.fetch(:bundle_roles, false) + opts[:roles] = roles if roles + + context.send :namespace, :bundle do + send :desc, <<-DESC + Install the current Bundler environment. By default, gems will be \ + installed to the shared/bundle path. Gems in the development and \ + test group will not be installed. The install command is executed \ + with the --deployment and --quiet flags. If the bundle cmd cannot \ + be found then you can override the bundle_cmd variable to specify \ + which one it should use. The base path to the app is fetched from \ + the :latest_release variable. Set it for custom deploy layouts. + + You can override any of these defaults by setting the variables shown below. + + N.B. bundle_roles must be defined before you require 'bundler/#{context_name}' \ + in your deploy.rb file. + + set :bundle_gemfile, "Gemfile" + set :bundle_dir, File.join(fetch(:shared_path), 'bundle') + set :bundle_flags, "--deployment --quiet" + set :bundle_without, [:development, :test] + set :bundle_with, [:mysql] + set :bundle_cmd, "bundle" # e.g. "/opt/ruby/bin/bundle" + set :bundle_roles, #{role_default} # e.g. [:app, :batch] + DESC + send task_method, :install, opts do + bundle_cmd = context.fetch(:bundle_cmd, "bundle") + bundle_flags = context.fetch(:bundle_flags, "--deployment --quiet") + bundle_dir = context.fetch(:bundle_dir, File.join(context.fetch(:shared_path), "bundle")) + bundle_gemfile = context.fetch(:bundle_gemfile, "Gemfile") + bundle_without = [*context.fetch(:bundle_without, [:development, :test])].compact + bundle_with = [*context.fetch(:bundle_with, [])].compact + app_path = context.fetch(:latest_release) + if app_path.to_s.empty? + raise error_type.new("Cannot detect current release path - make sure you have deployed at least once.") + end + args = ["--gemfile #{File.join(app_path, bundle_gemfile)}"] + args << "--path #{bundle_dir}" unless bundle_dir.to_s.empty? + args << bundle_flags.to_s + args << "--without #{bundle_without.join(" ")}" unless bundle_without.empty? + args << "--with #{bundle_with.join(" ")}" unless bundle_with.empty? + + run "cd #{app_path} && #{bundle_cmd} install #{args.join(" ")}" + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/deprecate.rb b/games/FNaFB2/Ruby/stdlib/bundler/deprecate.rb new file mode 100644 index 0000000..f595336 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/deprecate.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +begin + require "rubygems/deprecate" +rescue LoadError + # it's fine if it doesn't exist on the current RubyGems... + nil +end + +module Bundler + # If Bundler::Deprecate is an autoload constant, we need to define it + if defined?(Bundler::Deprecate) && !autoload?(:Deprecate) + # nothing to do! + elsif defined? ::Deprecate + Deprecate = ::Deprecate + elsif defined? Gem::Deprecate + Deprecate = Gem::Deprecate + else + class Deprecate + end + end + + unless Deprecate.respond_to?(:skip_during) + def Deprecate.skip_during + original = skip + self.skip = true + yield + ensure + self.skip = original + end + end + + unless Deprecate.respond_to?(:skip) + def Deprecate.skip + @skip ||= false + end + end + + unless Deprecate.respond_to?(:skip=) + def Deprecate.skip=(skip) + @skip = skip + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/digest.rb b/games/FNaFB2/Ruby/stdlib/bundler/digest.rb new file mode 100644 index 0000000..759f609 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/digest.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +# This code was extracted from https://github.com/Solistra/ruby-digest which is under public domain +module Bundler + module Digest + # The initial constant values for the 32-bit constant words A, B, C, D, and + # E, respectively. + SHA1_WORDS = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0].freeze + + # The 8-bit field used for bitwise `AND` masking. Defaults to `0xFFFFFFFF`. + SHA1_MASK = 0xFFFFFFFF + + class << self + def sha1(string) + unless string.is_a?(String) + raise TypeError, "can't convert #{string.class.inspect} into String" + end + + buffer = string.b + + words = SHA1_WORDS.dup + generate_split_buffer(buffer) do |chunk| + w = [] + chunk.each_slice(4) do |a, b, c, d| + w << (((a << 8 | b) << 8 | c) << 8 | d) + end + a, b, c, d, e = *words + (16..79).each do |i| + w[i] = SHA1_MASK & rotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1) + end + 0.upto(79) do |i| + case i + when 0..19 + f = ((b & c) | (~b & d)) + k = 0x5A827999 + when 20..39 + f = (b ^ c ^ d) + k = 0x6ED9EBA1 + when 40..59 + f = ((b & c) | (b & d) | (c & d)) + k = 0x8F1BBCDC + when 60..79 + f = (b ^ c ^ d) + k = 0xCA62C1D6 + end + t = SHA1_MASK & (SHA1_MASK & rotate(a, 5) + f + e + k + w[i]) + a, b, c, d, e = t, a, SHA1_MASK & rotate(b, 30), c, d # rubocop:disable Style/ParallelAssignment + end + mutated = [a, b, c, d, e] + words.map!.with_index {|word, index| SHA1_MASK & (word + mutated[index]) } + end + + words.pack("N*").unpack("H*").first + end + + private + + def generate_split_buffer(string, &block) + size = string.bytesize * 8 + buffer = string.bytes << 128 + buffer << 0 while buffer.size % 64 != 56 + buffer.concat([size].pack("Q>").bytes) + buffer.each_slice(64, &block) + end + + def rotate(value, spaces) + value << spaces | value >> (32 - spaces) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/dsl.rb b/games/FNaFB2/Ruby/stdlib/bundler/dsl.rb new file mode 100644 index 0000000..547db16 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/dsl.rb @@ -0,0 +1,583 @@ +# frozen_string_literal: true + +require_relative "dependency" +require_relative "ruby_dsl" + +module Bundler + class Dsl + include RubyDsl + + def self.evaluate(gemfile, lockfile, unlock) + builder = new + builder.eval_gemfile(gemfile) + builder.to_definition(lockfile, unlock) + end + + VALID_PLATFORMS = Bundler::Dependency::PLATFORM_MAP.keys.freeze + + VALID_KEYS = %w[group groups git path glob name branch ref tag require submodules + platform platforms type source install_if gemfile force_ruby_platform].freeze + + GITHUB_PULL_REQUEST_URL = %r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}.freeze + + attr_reader :gemspecs + attr_accessor :dependencies + + def initialize + @source = nil + @sources = SourceList.new + @git_sources = {} + @dependencies = [] + @groups = [] + @install_conditionals = [] + @optional_groups = [] + @platforms = [] + @env = nil + @ruby_version = nil + @gemspecs = [] + @gemfile = nil + @gemfiles = [] + add_git_sources + end + + def eval_gemfile(gemfile, contents = nil) + expanded_gemfile_path = Pathname.new(gemfile).expand_path(@gemfile && @gemfile.parent) + original_gemfile = @gemfile + @gemfile = expanded_gemfile_path + @gemfiles << expanded_gemfile_path + contents ||= Bundler.read_file(@gemfile.to_s) + instance_eval(contents.dup.tap {|x| x.untaint if RUBY_VERSION < "2.7" }, gemfile.to_s, 1) + rescue Exception => e # rubocop:disable Lint/RescueException + message = "There was an error " \ + "#{e.is_a?(GemfileEvalError) ? "evaluating" : "parsing"} " \ + "`#{File.basename gemfile.to_s}`: #{e.message}" + + raise DSLError.new(message, gemfile, e.backtrace, contents) + ensure + @gemfile = original_gemfile + end + + def gemspec(opts = nil) + opts ||= {} + path = opts[:path] || "." + glob = opts[:glob] + name = opts[:name] + development_group = opts[:development_group] || :development + expanded_path = gemfile_root.join(path) + + gemspecs = Gem::Util.glob_files_in_dir("{,*}.gemspec", expanded_path).map {|g| Bundler.load_gemspec(g) }.compact + gemspecs.reject! {|s| s.name != name } if name + specs_by_name_and_version = gemspecs.group_by {|s| [s.name, s.version] } + + case specs_by_name_and_version.size + when 1 + specs = specs_by_name_and_version.values.first + spec = specs.find {|s| s.match_platform(Bundler.local_platform) } || specs.first + + @gemspecs << spec + + gem spec.name, :name => spec.name, :path => path, :glob => glob + + group(development_group) do + spec.development_dependencies.each do |dep| + gem dep.name, *(dep.requirement.as_list + [:type => :development]) + end + end + when 0 + raise InvalidOption, "There are no gemspecs at #{expanded_path}" + else + raise InvalidOption, "There are multiple gemspecs at #{expanded_path}. " \ + "Please use the :name option to specify which one should be used" + end + end + + def gem(name, *args) + options = args.last.is_a?(Hash) ? args.pop.dup : {} + options["gemfile"] = @gemfile + version = args || [">= 0"] + + normalize_options(name, version, options) + + dep = Dependency.new(name, version, options) + + # if there's already a dependency with this name we try to prefer one + if current = @dependencies.find {|d| d.name == dep.name } + deleted_dep = @dependencies.delete(current) if current.type == :development + + unless deleted_dep + if current.requirement != dep.requirement + return if dep.type == :development + + update_prompt = "" + + if File.basename(@gemfile) == Injector::INJECTED_GEMS + if dep.requirements_list.include?(">= 0") && !current.requirements_list.include?(">= 0") + update_prompt = ". Gem already added" + else + update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`" + + update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current.requirements_list.include?(">= 0") + end + end + + raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \ + "You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \ + "#{update_prompt}" + elsif current.source != dep.source + return if dep.type == :development + raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \ + "You specified that #{dep.name} (#{dep.requirement}) should come from " \ + "#{current.source || "an unspecified source"} and #{dep.source}\n" + else + Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \ + "You should probably keep only one of them.\n" \ + "Remove any duplicate entries and specify the gem only once.\n" \ + "While it's not a problem now, it could cause errors if you change the version of one of them later." + end + end + end + + @dependencies << dep + end + + def source(source, *args, &blk) + options = args.last.is_a?(Hash) ? args.pop.dup : {} + options = normalize_hash(options) + source = normalize_source(source) + + if options.key?("type") + options["type"] = options["type"].to_s + unless Plugin.source?(options["type"]) + raise InvalidOption, "No plugin sources available for #{options["type"]}" + end + + unless block_given? + raise InvalidOption, "You need to pass a block to #source with :type option" + end + + source_opts = options.merge("uri" => source) + with_source(@sources.add_plugin_source(options["type"], source_opts), &blk) + elsif block_given? + with_source(@sources.add_rubygems_source("remotes" => source), &blk) + else + @sources.add_global_rubygems_remote(source) + end + end + + def git_source(name, &block) + unless block_given? + raise InvalidOption, "You need to pass a block to #git_source" + end + + if valid_keys.include?(name.to_s) + raise InvalidOption, "You cannot use #{name} as a git source. It " \ + "is a reserved key. Reserved keys are: #{valid_keys.join(", ")}" + end + + @git_sources[name.to_s] = block + end + + def path(path, options = {}, &blk) + source_options = normalize_hash(options).merge( + "path" => Pathname.new(path), + "root_path" => gemfile_root, + "gemspec" => gemspecs.find {|g| g.name == options["name"] } + ) + + source_options["global"] = true unless block_given? + + source = @sources.add_path_source(source_options) + with_source(source, &blk) + end + + def git(uri, options = {}, &blk) + unless block_given? + msg = "You can no longer specify a git source by itself. Instead, \n" \ + "either use the :git option on a gem, or specify the gems that \n" \ + "bundler should find in the git source by passing a block to \n" \ + "the git method, like: \n\n" \ + " git 'git://github.com/rails/rails.git' do\n" \ + " gem 'rails'\n" \ + " end" + raise DeprecatedError, msg + end + + with_source(@sources.add_git_source(normalize_hash(options).merge("uri" => uri)), &blk) + end + + def github(repo, options = {}) + raise ArgumentError, "GitHub sources require a block" unless block_given? + github_uri = @git_sources["github"].call(repo) + git_options = normalize_hash(options).merge("uri" => github_uri) + git_source = @sources.add_git_source(git_options) + with_source(git_source) { yield } + end + + def to_definition(lockfile, unlock) + check_primary_source_safety + Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles) + end + + def group(*args, &blk) + options = args.last.is_a?(Hash) ? args.pop.dup : {} + normalize_group_options(options, args) + + @groups.concat args + + if options["optional"] + optional_groups = args - @optional_groups + @optional_groups.concat optional_groups + end + + yield + ensure + args.each { @groups.pop } + end + + def install_if(*args) + @install_conditionals.concat args + yield + ensure + args.each { @install_conditionals.pop } + end + + def platforms(*platforms) + @platforms.concat platforms + yield + ensure + platforms.each { @platforms.pop } + end + alias_method :platform, :platforms + + def env(name) + old = @env + @env = name + yield + ensure + @env = old + end + + def plugin(*args) + # Pass on + end + + def method_missing(name, *args) + raise GemfileError, "Undefined local variable or method `#{name}' for Gemfile" + end + + def check_primary_source_safety + check_path_source_safety + check_rubygems_source_safety + end + + private + + def add_git_sources + git_source(:github) do |repo_name| + if repo_name =~ GITHUB_PULL_REQUEST_URL + { + "git" => "https://github.com/#{$1}.git", + "branch" => "refs/pull/#{$2}/head", + "ref" => nil, + "tag" => nil, + } + else + repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") + "https://github.com/#{repo_name}.git" + end + end + + git_source(:gist) do |repo_name| + "https://gist.github.com/#{repo_name}.git" + end + + git_source(:bitbucket) do |repo_name| + user_name, repo_name = repo_name.split("/") + repo_name ||= user_name + "https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git" + end + end + + def with_source(source) + old_source = @source + if block_given? + @source = source + yield + end + source + ensure + @source = old_source + end + + def normalize_hash(opts) + opts.keys.each do |k| + opts[k.to_s] = opts.delete(k) unless k.is_a?(String) + end + opts + end + + def valid_keys + @valid_keys ||= VALID_KEYS + end + + def normalize_options(name, version, opts) + if name.is_a?(Symbol) + raise GemfileError, %(You need to specify gem names as Strings. Use 'gem "#{name}"' instead) + end + if name =~ /\s/ + raise GemfileError, %('#{name}' is not a valid gem name because it contains whitespace) + end + raise GemfileError, %(an empty gem name is not valid) if name.empty? + + normalize_hash(opts) + + git_names = @git_sources.keys.map(&:to_s) + validate_keys("gem '#{name}'", opts, valid_keys + git_names) + + groups = @groups.dup + opts["group"] = opts.delete("groups") || opts["group"] + groups.concat Array(opts.delete("group")) + groups = [:default] if groups.empty? + + install_if = @install_conditionals.dup + install_if.concat Array(opts.delete("install_if")) + install_if = install_if.reduce(true) do |memo, val| + memo && (val.respond_to?(:call) ? val.call : val) + end + + platforms = @platforms.dup + opts["platforms"] = opts["platform"] || opts["platforms"] + platforms.concat Array(opts.delete("platforms")) + platforms.map!(&:to_sym) + platforms.each do |p| + next if VALID_PLATFORMS.include?(p) + raise GemfileError, "`#{p}` is not a valid platform. The available options are: #{VALID_PLATFORMS.inspect}" + end + + # Save sources passed in a key + if opts.key?("source") + source = normalize_source(opts["source"]) + opts["source"] = @sources.add_rubygems_source("remotes" => source) + end + + git_name = (git_names & opts.keys).last + if @git_sources[git_name] + git_opts = @git_sources[git_name].call(opts[git_name]) + git_opts = { "git" => git_opts } if git_opts.is_a?(String) + opts.merge!(git_opts) do |key, _gemfile_value, _git_source_value| + raise GemfileError, %(The :#{key} option can't be used with `#{git_name}: #{opts[git_name].inspect}`) + end + end + + %w[git path].each do |type| + next unless param = opts[type] + if version.first && version.first =~ /^\s*=?\s*(\d[^\s]*)\s*$/ + options = opts.merge("name" => name, "version" => $1) + else + options = opts.dup + end + source = send(type, param, options) {} + opts["source"] = source + end + + opts["source"] ||= @source + opts["env"] ||= @env + opts["platforms"] = platforms.dup + opts["group"] = groups + opts["should_include"] = install_if + end + + def normalize_group_options(opts, groups) + normalize_hash(opts) + + groups = groups.map {|group| ":#{group}" }.join(", ") + validate_keys("group #{groups}", opts, %w[optional]) + + opts["optional"] ||= false + end + + def validate_keys(command, opts, valid_keys) + invalid_keys = opts.keys - valid_keys + + git_source = opts.keys & @git_sources.keys.map(&:to_s) + if opts["branch"] && !(opts["git"] || opts["github"] || git_source.any?) + raise GemfileError, %(The `branch` option for `#{command}` is not allowed. Only gems with a git source can specify a branch) + end + + return true unless invalid_keys.any? + + message = String.new + message << "You passed #{invalid_keys.map {|k| ":" + k }.join(", ")} " + message << if invalid_keys.size > 1 + "as options for #{command}, but they are invalid." + else + "as an option for #{command}, but it is invalid." + end + + message << " Valid options are: #{valid_keys.join(", ")}." + message << " You may be able to resolve this by upgrading Bundler to the newest version." + raise InvalidOption, message + end + + def normalize_source(source) + case source + when :gemcutter, :rubygems, :rubyforge + Bundler::SharedHelpers.major_deprecation 2, "The source :#{source} is deprecated because HTTP " \ + "requests are insecure.\nPlease change your source to 'https://" \ + "rubygems.org' if possible, or 'http://rubygems.org' if not." + "http://rubygems.org" + when String + source + else + raise GemfileError, "Unknown source '#{source}'" + end + end + + def check_path_source_safety + return if @sources.global_path_source.nil? + + msg = "You can no longer specify a path source by itself. Instead, \n" \ + "either use the :path option on a gem, or specify the gems that \n" \ + "bundler should find in the path source by passing a block to \n" \ + "the path method, like: \n\n" \ + " path 'dir/containing/rails' do\n" \ + " gem 'rails'\n" \ + " end\n\n" + + SharedHelpers.major_deprecation(2, msg.strip) + end + + def check_rubygems_source_safety + if @sources.implicit_global_source? + implicit_global_source_warning + elsif @sources.aggregate_global_source? + multiple_global_source_warning + end + end + + def implicit_global_source_warning + Bundler::SharedHelpers.major_deprecation 2, "This Gemfile does not include an explicit global source. " \ + "Not using an explicit global source may result in a different lockfile being generated depending on " \ + "the gems you have installed locally before bundler is run. " \ + "Instead, define a global source in your Gemfile like this: source \"https://rubygems.org\"." + end + + def multiple_global_source_warning + if Bundler.feature_flag.bundler_3_mode? + msg = "This Gemfile contains multiple global sources. " \ + "Each source after the first must include a block to indicate which gems " \ + "should come from that source" + raise GemfileEvalError, msg + else + Bundler::SharedHelpers.major_deprecation 2, "Your Gemfile contains multiple global sources. " \ + "Using `source` more than once without a block is a security risk, and " \ + "may result in installing unexpected gems. To resolve this warning, use " \ + "a block to indicate which gems should come from the secondary source." + end + end + + class DSLError < GemfileError + # @return [String] the description that should be presented to the user. + # + attr_reader :description + + # @return [String] the path of the dsl file that raised the exception. + # + attr_reader :dsl_path + + # @return [Exception] the backtrace of the exception raised by the + # evaluation of the dsl file. + # + attr_reader :backtrace + + # @param [Exception] backtrace @see backtrace + # @param [String] dsl_path @see dsl_path + # + def initialize(description, dsl_path, backtrace, contents = nil) + @status_code = $!.respond_to?(:status_code) && $!.status_code + + @description = description + @dsl_path = dsl_path + @backtrace = backtrace + @contents = contents + end + + def status_code + @status_code || super + end + + # @return [String] the contents of the DSL that cause the exception to + # be raised. + # + def contents + @contents ||= dsl_path && File.exist?(dsl_path) && File.read(dsl_path) + end + + # The message of the exception reports the content of podspec for the + # line that generated the original exception. + # + # @example Output + # + # Invalid podspec at `RestKit.podspec` - undefined method + # `exclude_header_search_paths=' for # + # + # from spec-repos/master/RestKit/0.9.3/RestKit.podspec:36 + # ------------------------------------------- + # # because it would break: #import + # > ns.exclude_header_search_paths = 'Code/RestKit.h' + # end + # ------------------------------------------- + # + # @return [String] the message of the exception. + # + def to_s + @to_s ||= begin + trace_line, description = parse_line_number_from_description + + m = String.new("\n[!] ") + m << description + m << ". Bundler cannot continue.\n" + + return m unless backtrace && dsl_path && contents + + trace_line = backtrace.find {|l| l.include?(dsl_path.to_s) } || trace_line + return m unless trace_line + line_numer = trace_line.split(":")[1].to_i - 1 + return m unless line_numer + + lines = contents.lines.to_a + indent = " # " + indicator = indent.tr("#", ">") + first_line = line_numer.zero? + last_line = (line_numer == (lines.count - 1)) + + m << "\n" + m << "#{indent}from #{trace_line.gsub(/:in.*$/, "")}\n" + m << "#{indent}-------------------------------------------\n" + m << "#{indent}#{lines[line_numer - 1]}" unless first_line + m << "#{indicator}#{lines[line_numer]}" + m << "#{indent}#{lines[line_numer + 1]}" unless last_line + m << "\n" unless m.end_with?("\n") + m << "#{indent}-------------------------------------------\n" + end + end + + private + + def parse_line_number_from_description + description = self.description + if dsl_path && description =~ /((#{Regexp.quote File.expand_path(dsl_path)}|#{Regexp.quote dsl_path.to_s}):\d+)/ + trace_line = Regexp.last_match[1] + description = description.sub(/\n.*\n(\.\.\.)? *\^~+$/, "").sub(/#{Regexp.quote trace_line}:\s*/, "").sub("\n", " - ") + end + [trace_line, description] + end + end + + def gemfile_root + @gemfile ||= Bundler.default_gemfile + @gemfile.dirname + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/endpoint_specification.rb b/games/FNaFB2/Ruby/stdlib/bundler/endpoint_specification.rb new file mode 100644 index 0000000..d315d1c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/endpoint_specification.rb @@ -0,0 +1,147 @@ +# frozen_string_literal: true + +module Bundler + # used for Creating Specifications from the Gemcutter Endpoint + class EndpointSpecification < Gem::Specification + include MatchRemoteMetadata + + attr_reader :name, :version, :platform, :checksum + attr_accessor :source, :remote, :dependencies + + def initialize(name, version, platform, spec_fetcher, dependencies, metadata = nil) + super() + @name = name + @version = Gem::Version.create version + @platform = Gem::Platform.new(platform) + @spec_fetcher = spec_fetcher + @dependencies = dependencies.map {|dep, reqs| build_dependency(dep, reqs) } + + @loaded_from = nil + @remote_specification = nil + + parse_metadata(metadata) + end + + def fetch_platform + @platform + end + + def identifier + @__identifier ||= [name, version, platform.to_s] + end + + # needed for standalone, load required_paths from local gemspec + # after the gem is installed + def require_paths + if @remote_specification + @remote_specification.require_paths + elsif _local_specification + _local_specification.require_paths + else + super + end + end + + # needed for inline + def load_paths + # remote specs aren't installed, and can't have load_paths + if _local_specification + _local_specification.load_paths + else + super + end + end + + # needed for binstubs + def executables + if @remote_specification + @remote_specification.executables + elsif _local_specification + _local_specification.executables + else + super + end + end + + # needed for bundle clean + def bindir + if @remote_specification + @remote_specification.bindir + elsif _local_specification + _local_specification.bindir + else + super + end + end + + # needed for post_install_messages during install + def post_install_message + if @remote_specification + @remote_specification.post_install_message + elsif _local_specification + _local_specification.post_install_message + else + super + end + end + + # needed for "with native extensions" during install + def extensions + if @remote_specification + @remote_specification.extensions + elsif _local_specification + _local_specification.extensions + else + super + end + end + + def _local_specification + return unless @loaded_from && File.exist?(local_specification_path) + eval(File.read(local_specification_path)).tap do |spec| + spec.loaded_from = @loaded_from + end + end + + def __swap__(spec) + SharedHelpers.ensure_same_dependencies(self, dependencies, spec.dependencies) + @remote_specification = spec + end + + private + + def _remote_specification + @_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @platform]) + end + + def local_specification_path + "#{base_dir}/specifications/#{full_name}.gemspec" + end + + def parse_metadata(data) + unless data + @required_ruby_version = nil + @required_rubygems_version = nil + return + end + + data.each do |k, v| + next unless v + case k.to_s + when "checksum" + @checksum = v.last + when "rubygems" + @required_rubygems_version = Gem::Requirement.new(v) + when "ruby" + @required_ruby_version = Gem::Requirement.new(v) + end + end + rescue StandardError => e + raise GemspecError, "There was an error parsing the metadata for the gem #{name} (#{version}): #{e.class}\n#{e}\nThe metadata was #{data.inspect}" + end + + def build_dependency(name, requirements) + Gem::Dependency.new(name, requirements) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/env.rb b/games/FNaFB2/Ruby/stdlib/bundler/env.rb new file mode 100644 index 0000000..1763035 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/env.rb @@ -0,0 +1,150 @@ +# frozen_string_literal: true + +require_relative "rubygems_integration" +require_relative "source/git/git_proxy" + +module Bundler + class Env + def self.write(io) + io.write report + end + + def self.report(options = {}) + print_gemfile = options.delete(:print_gemfile) { true } + print_gemspecs = options.delete(:print_gemspecs) { true } + + out = String.new + append_formatted_table("Environment", environment, out) + append_formatted_table("Bundler Build Metadata", BuildMetadata.to_h, out) + + unless Bundler.settings.all.empty? + out << "\n## Bundler settings\n\n```\n" + Bundler.settings.all.each do |setting| + out << setting << "\n" + Bundler.settings.pretty_values_for(setting).each do |line| + out << " " << line << "\n" + end + end + out << "```\n" + end + + return out unless SharedHelpers.in_bundle? + + if print_gemfile + gemfiles = [Bundler.default_gemfile] + begin + gemfiles = Bundler.definition.gemfiles + rescue GemfileNotFound + nil + end + + out << "\n## Gemfile\n" + gemfiles.each do |gemfile| + out << "\n### #{Pathname.new(gemfile).relative_path_from(SharedHelpers.pwd)}\n\n" + out << "```ruby\n" << read_file(gemfile).chomp << "\n```\n" + end + + out << "\n### #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}\n\n" + out << "```\n" << read_file(Bundler.default_lockfile).chomp << "\n```\n" + end + + if print_gemspecs + dsl = Dsl.new.tap {|d| d.eval_gemfile(Bundler.default_gemfile) } + out << "\n## Gemspecs\n" unless dsl.gemspecs.empty? + dsl.gemspecs.each do |gs| + out << "\n### #{File.basename(gs.loaded_from)}" + out << "\n\n```ruby\n" << read_file(gs.loaded_from).chomp << "\n```\n" + end + end + + out + end + + def self.read_file(filename) + Bundler.read_file(filename.to_s).strip + rescue Errno::ENOENT + "" + rescue RuntimeError => e + "#{e.class}: #{e.message}" + end + + def self.ruby_version + str = String.new(RUBY_VERSION) + str << "p#{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL + str << " (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION}) [#{Gem::Platform.local}]" + end + + def self.git_version + Bundler::Source::Git::GitProxy.new(nil, nil, nil).full_version + rescue Bundler::Source::Git::GitNotInstalledError + "not installed" + end + + def self.version_of(script) + return "not installed" unless Bundler.which(script) + `#{script} --version`.chomp + end + + def self.chruby_version + return "not installed" unless Bundler.which("chruby-exec") + `chruby-exec -- chruby --version`. + sub(/.*^chruby: (#{Gem::Version::VERSION_PATTERN}).*/m, '\1') + end + + def self.environment + out = [] + + out << ["Bundler", Bundler::VERSION] + out << [" Platforms", Gem.platforms.join(", ")] + out << ["Ruby", ruby_version] + out << [" Full Path", Gem.ruby] + out << [" Config Dir", Pathname.new(Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE).dirname] + out << ["RubyGems", Gem::VERSION] + out << [" Gem Home", Gem.dir] + out << [" Gem Path", Gem.path.join(File::PATH_SEPARATOR)] + out << [" User Home", Gem.user_home] + out << [" User Path", Gem.user_dir] + out << [" Bin Dir", Gem.bindir] + if defined?(OpenSSL::SSL) + out << ["OpenSSL"] + out << [" Compiled", OpenSSL::OPENSSL_VERSION] if defined?(OpenSSL::OPENSSL_VERSION) + out << [" Loaded", OpenSSL::OPENSSL_LIBRARY_VERSION] if defined?(OpenSSL::OPENSSL_LIBRARY_VERSION) + out << [" Cert File", OpenSSL::X509::DEFAULT_CERT_FILE] if defined?(OpenSSL::X509::DEFAULT_CERT_FILE) + out << [" Cert Dir", OpenSSL::X509::DEFAULT_CERT_DIR] if defined?(OpenSSL::X509::DEFAULT_CERT_DIR) + end + out << ["Tools"] + out << [" Git", git_version] + out << [" RVM", ENV.fetch("rvm_version") { version_of("rvm") }] + out << [" rbenv", version_of("rbenv")] + out << [" chruby", chruby_version] + + %w[rubygems-bundler open_gem].each do |name| + specs = Bundler.rubygems.find_name(name) + out << [" #{name}", "(#{specs.map(&:version).join(",")})"] unless specs.empty? + end + if (exe = caller.last.split(":").first) && exe =~ %r{(exe|bin)/bundler?\z} + shebang = File.read(exe).lines.first + shebang.sub!(/^#!\s*/, "") + unless shebang.start_with?(Gem.ruby, "/usr/bin/env ruby") + out << ["Gem.ruby", Gem.ruby] + out << ["bundle #!", shebang] + end + end + + out + end + + def self.append_formatted_table(title, pairs, out) + return if pairs.empty? + out << "\n" unless out.empty? + out << "## #{title}\n\n```\n" + ljust = pairs.map {|k, _v| k.to_s.length }.max + pairs.each do |k, v| + out << "#{k.to_s.ljust(ljust)} #{v}\n" + end + out << "```\n" + end + + private_class_method :read_file, :ruby_version, :git_version, :append_formatted_table, :version_of, :chruby_version + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/environment_preserver.rb b/games/FNaFB2/Ruby/stdlib/bundler/environment_preserver.rb new file mode 100644 index 0000000..0f08e04 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/environment_preserver.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +module Bundler + class EnvironmentPreserver + INTENTIONALLY_NIL = "BUNDLER_ENVIRONMENT_PRESERVER_INTENTIONALLY_NIL".freeze + BUNDLER_KEYS = %w[ + BUNDLE_BIN_PATH + BUNDLE_GEMFILE + BUNDLER_VERSION + GEM_HOME + GEM_PATH + MANPATH + PATH + RB_USER_INSTALL + RUBYLIB + RUBYOPT + ].map(&:freeze).freeze + BUNDLER_PREFIX = "BUNDLER_ORIG_".freeze + + def self.from_env + new(env_to_hash(ENV), BUNDLER_KEYS) + end + + def self.env_to_hash(env) + to_hash = env.to_hash + return to_hash unless Gem.win_platform? + + to_hash.each_with_object({}) {|(k,v), a| a[k.upcase] = v } + end + + # @param env [Hash] + # @param keys [Array] + def initialize(env, keys) + @original = env + @keys = keys + @prefix = BUNDLER_PREFIX + end + + # Replaces `ENV` with the bundler environment variables backed up + def replace_with_backup + unless Gem.win_platform? + ENV.replace(backup) + return + end + + # Fallback logic for Windows below to workaround + # https://bugs.ruby-lang.org/issues/16798. Can be dropped once all + # supported rubies include the fix for that. + + ENV.clear + + backup.each {|k, v| ENV[k] = v } + end + + # @return [Hash] + def backup + env = @original.clone + @keys.each do |key| + value = env[key] + if !value.nil? && !value.empty? + env[@prefix + key] ||= value + elsif value.nil? + env[@prefix + key] ||= INTENTIONALLY_NIL + end + end + env + end + + # @return [Hash] + def restore + env = @original.clone + @keys.each do |key| + value_original = env[@prefix + key] + next if value_original.nil? || value_original.empty? + if value_original == INTENTIONALLY_NIL + env.delete(key) + else + env[key] = value_original + end + env.delete(@prefix + key) + end + env + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/errors.rb b/games/FNaFB2/Ruby/stdlib/bundler/errors.rb new file mode 100644 index 0000000..f10b6cc --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/errors.rb @@ -0,0 +1,185 @@ +# frozen_string_literal: true + +module Bundler + class BundlerError < StandardError + def self.status_code(code) + define_method(:status_code) { code } + if match = BundlerError.all_errors.find {|_k, v| v == code } + error, _ = match + raise ArgumentError, + "Trying to register #{self} for status code #{code} but #{error} is already registered" + end + BundlerError.all_errors[self] = code + end + + def self.all_errors + @all_errors ||= {} + end + end + + class GemfileError < BundlerError; status_code(4); end + class InstallError < BundlerError; status_code(5); end + + # Internal error, should be rescued + class VersionConflict < BundlerError + attr_reader :conflicts + + def initialize(conflicts, msg = nil) + super(msg) + @conflicts = conflicts + end + + status_code(6) + end + + class GemNotFound < BundlerError; status_code(7); end + class InstallHookError < BundlerError; status_code(8); end + class GemfileNotFound < BundlerError; status_code(10); end + class GitError < BundlerError; status_code(11); end + class DeprecatedError < BundlerError; status_code(12); end + class PathError < BundlerError; status_code(13); end + class GemspecError < BundlerError; status_code(14); end + class InvalidOption < BundlerError; status_code(15); end + class ProductionError < BundlerError; status_code(16); end + + class HTTPError < BundlerError + status_code(17) + def filter_uri(uri) + URICredentialsFilter.credential_filtered_uri(uri) + end + end + + class RubyVersionMismatch < BundlerError; status_code(18); end + class SecurityError < BundlerError; status_code(19); end + class LockfileError < BundlerError; status_code(20); end + class CyclicDependencyError < BundlerError; status_code(21); end + class GemfileLockNotFound < BundlerError; status_code(22); end + class PluginError < BundlerError; status_code(29); end + class SudoNotPermittedError < BundlerError; status_code(30); end + class ThreadCreationError < BundlerError; status_code(33); end + class APIResponseMismatchError < BundlerError; status_code(34); end + class APIResponseInvalidDependenciesError < BundlerError; status_code(35); end + class GemfileEvalError < GemfileError; end + class MarshalError < StandardError; end + + class PermissionError < BundlerError + def initialize(path, permission_type = :write) + @path = path + @permission_type = permission_type + end + + def action + case @permission_type + when :read then "read from" + when :write then "write to" + when :executable, :exec then "execute" + else @permission_type.to_s + end + end + + def permission_type + case @permission_type + when :create + "executable permissions for all parent directories and write permissions for `#{parent_folder}`" + else + "#{@permission_type} permissions for that path" + end + end + + def parent_folder + File.dirname(@path) + end + + def message + "There was an error while trying to #{action} `#{@path}`. " \ + "It is likely that you need to grant #{permission_type}." + end + + status_code(23) + end + + class GemRequireError < BundlerError + attr_reader :orig_exception + + def initialize(orig_exception, msg) + full_message = msg + "\nGem Load Error is: #{orig_exception.message}\n"\ + "Backtrace for gem load error is:\n"\ + "#{orig_exception.backtrace.join("\n")}\n"\ + "Bundler Error Backtrace:\n" + super(full_message) + @orig_exception = orig_exception + end + + status_code(24) + end + + class YamlSyntaxError < BundlerError + attr_reader :orig_exception + + def initialize(orig_exception, msg) + super(msg) + @orig_exception = orig_exception + end + + status_code(25) + end + + class TemporaryResourceError < PermissionError + def message + "There was an error while trying to #{action} `#{@path}`. " \ + "Some resource was temporarily unavailable. It's suggested that you try" \ + "the operation again." + end + + status_code(26) + end + + class VirtualProtocolError < BundlerError + def message + "There was an error relating to virtualization and file access. " \ + "It is likely that you need to grant access to or mount some file system correctly." + end + + status_code(27) + end + + class OperationNotSupportedError < PermissionError + def message + "Attempting to #{action} `#{@path}` is unsupported by your OS." + end + + status_code(28) + end + + class NoSpaceOnDeviceError < PermissionError + def message + "There was an error while trying to #{action} `#{@path}`. " \ + "There was insufficient space remaining on the device." + end + + status_code(31) + end + + class GenericSystemCallError < BundlerError + attr_reader :underlying_error + + def initialize(underlying_error, message) + @underlying_error = underlying_error + super("#{message}\nThe underlying system error is #{@underlying_error.class}: #{@underlying_error}") + end + + status_code(32) + end + + class DirectoryRemovalError < BundlerError + def initialize(orig_exception, msg) + full_message = "#{msg}.\n" \ + "The underlying error was #{orig_exception.class}: #{orig_exception.message}, with backtrace:\n" \ + " #{orig_exception.backtrace.join("\n ")}\n\n" \ + "Bundler Error Backtrace:" + super(full_message) + end + + status_code(36) + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/feature_flag.rb b/games/FNaFB2/Ruby/stdlib/bundler/feature_flag.rb new file mode 100644 index 0000000..983de31 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/feature_flag.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module Bundler + class FeatureFlag + def self.settings_flag(flag, &default) + unless Bundler::Settings::BOOL_KEYS.include?(flag.to_s) + raise "Cannot use `#{flag}` as a settings feature flag since it isn't a bool key" + end + + settings_method("#{flag}?", flag, &default) + end + private_class_method :settings_flag + + def self.settings_option(key, &default) + settings_method(key, key, &default) + end + private_class_method :settings_option + + def self.settings_method(name, key, &default) + define_method(name) do + value = Bundler.settings[key] + value = instance_eval(&default) if value.nil? + value + end + end + private_class_method :settings_method + + (1..10).each {|v| define_method("bundler_#{v}_mode?") { major_version >= v } } + + settings_flag(:allow_offline_install) { bundler_3_mode? } + settings_flag(:auto_clean_without_path) { bundler_3_mode? } + settings_flag(:cache_all) { bundler_3_mode? } + settings_flag(:default_install_uses_path) { bundler_3_mode? } + settings_flag(:forget_cli_options) { bundler_3_mode? } + settings_flag(:global_gem_cache) { bundler_3_mode? } + settings_flag(:path_relative_to_cwd) { bundler_3_mode? } + settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") } + settings_flag(:print_only_version_number) { bundler_3_mode? } + settings_flag(:setup_makes_kernel_gem_public) { !bundler_3_mode? } + settings_flag(:suppress_install_using_messages) { bundler_3_mode? } + settings_flag(:update_requires_all_flag) { bundler_4_mode? } + + settings_option(:default_cli_command) { bundler_3_mode? ? :cli_help : :install } + + def initialize(bundler_version) + @bundler_version = Gem::Version.create(bundler_version) + end + + def major_version + @bundler_version.segments.first + end + private :major_version + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/fetcher.rb b/games/FNaFB2/Ruby/stdlib/bundler/fetcher.rb new file mode 100644 index 0000000..e399a50 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/fetcher.rb @@ -0,0 +1,314 @@ +# frozen_string_literal: true + +require_relative "vendored_persistent" +require "cgi" +require "securerandom" +require "zlib" +require "rubygems/request" + +module Bundler + # Handles all the fetching with the rubygems server + class Fetcher + autoload :CompactIndex, File.expand_path("fetcher/compact_index", __dir__) + autoload :Downloader, File.expand_path("fetcher/downloader", __dir__) + autoload :Dependency, File.expand_path("fetcher/dependency", __dir__) + autoload :Index, File.expand_path("fetcher/index", __dir__) + + # This error is raised when it looks like the network is down + class NetworkDownError < HTTPError; end + # This error is raised if we should rate limit our requests to the API + class TooManyRequestsError < HTTPError; end + # This error is raised if the API returns a 413 (only printed in verbose) + class FallbackError < HTTPError; end + + # This is the error raised if OpenSSL fails the cert verification + class CertificateFailureError < HTTPError + def initialize(remote_uri) + remote_uri = filter_uri(remote_uri) + super "Could not verify the SSL certificate for #{remote_uri}.\nThere" \ + " is a chance you are experiencing a man-in-the-middle attack, but" \ + " most likely your system doesn't have the CA certificates needed" \ + " for verification. For information about OpenSSL certificates, see" \ + " https://railsapps.github.io/openssl-certificate-verify-failed.html." \ + " To connect without using SSL, edit your Gemfile" \ + " sources and change 'https' to 'http'." + end + end + + # This is the error raised when a source is HTTPS and OpenSSL didn't load + class SSLError < HTTPError + def initialize(msg = nil) + super msg || "Could not load OpenSSL.\n" \ + "You must recompile Ruby with OpenSSL support or change the sources in your " \ + "Gemfile from 'https' to 'http'. Instructions for compiling with OpenSSL " \ + "using RVM are available at rvm.io/packages/openssl." + end + end + + # This error is raised if HTTP authentication is required, but not provided. + class AuthenticationRequiredError < HTTPError + def initialize(remote_uri) + remote_uri = filter_uri(remote_uri) + super "Authentication is required for #{remote_uri}.\n" \ + "Please supply credentials for this source. You can do this by running:\n" \ + "`bundle config set --global #{remote_uri} username:password`\n" \ + "or by storing the credentials in the `#{Settings.key_for(remote_uri)}` environment variable" + end + end + + # This error is raised if HTTP authentication is provided, but incorrect. + class BadAuthenticationError < HTTPError + def initialize(remote_uri) + remote_uri = filter_uri(remote_uri) + super "Bad username or password for #{remote_uri}.\n" \ + "Please double-check your credentials and correct them." + end + end + + # Exceptions classes that should bypass retry attempts. If your password didn't work the + # first time, it's not going to the third time. + NET_ERRORS = [:HTTPBadGateway, :HTTPBadRequest, :HTTPFailedDependency, + :HTTPForbidden, :HTTPInsufficientStorage, :HTTPMethodNotAllowed, + :HTTPMovedPermanently, :HTTPNoContent, :HTTPNotFound, + :HTTPNotImplemented, :HTTPPreconditionFailed, :HTTPRequestEntityTooLarge, + :HTTPRequestURITooLong, :HTTPUnauthorized, :HTTPUnprocessableEntity, + :HTTPUnsupportedMediaType, :HTTPVersionNotSupported].freeze + FAIL_ERRORS = begin + fail_errors = [AuthenticationRequiredError, BadAuthenticationError, FallbackError] + fail_errors << Gem::Requirement::BadRequirementError + fail_errors.concat(NET_ERRORS.map {|e| Net.const_get(e) }) + end.freeze + + class << self + attr_accessor :disable_endpoint, :api_timeout, :redirect_limit, :max_retries + end + + self.redirect_limit = Bundler.settings[:redirect] # How many redirects to allow in one request + self.api_timeout = Bundler.settings[:timeout] # How long to wait for each API call + self.max_retries = Bundler.settings[:retry] # How many retries for the API call + + def initialize(remote) + @remote = remote + + Socket.do_not_reverse_lookup = true + connection # create persistent connection + end + + def uri + @remote.anonymized_uri + end + + # fetch a gem specification + def fetch_spec(spec) + spec -= [nil, "ruby", ""] + spec_file_name = "#{spec.join "-"}.gemspec" + + uri = Bundler::URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz") + if uri.scheme == "file" + path = Bundler.rubygems.correct_for_windows_path(uri.path) + Bundler.load_marshal Bundler.rubygems.inflate(Gem.read_binary(path)) + elsif cached_spec_path = gemspec_cached_path(spec_file_name) + Bundler.load_gemspec(cached_spec_path) + else + Bundler.load_marshal Bundler.rubygems.inflate(downloader.fetch(uri).body) + end + rescue MarshalError + raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \ + "Your network or your gem server is probably having issues right now." + end + + # return the specs in the bundler format as an index with retries + def specs_with_retry(gem_names, source) + Bundler::Retry.new("fetcher", FAIL_ERRORS).attempts do + specs(gem_names, source) + end + end + + # return the specs in the bundler format as an index + def specs(gem_names, source) + index = Bundler::Index.new + + if Bundler::Fetcher.disable_endpoint + @use_api = false + specs = fetchers.last.specs(gem_names) + else + specs = [] + @fetchers = fetchers.drop_while do |f| + !f.available? || (f.api_fetcher? && !gem_names) || !specs = f.specs(gem_names) + end + @use_api = false if fetchers.none?(&:api_fetcher?) + end + + specs.each do |name, version, platform, dependencies, metadata| + spec = if dependencies + EndpointSpecification.new(name, version, platform, self, dependencies, metadata) + else + RemoteSpecification.new(name, version, platform, self) + end + spec.source = source + spec.remote = @remote + index << spec + end + + index + rescue CertificateFailureError + Bundler.ui.info "" if gem_names && use_api # newline after dots + raise + end + + def use_api + return @use_api if defined?(@use_api) + + fetchers.shift until fetchers.first.available? + + @use_api = if remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint + false + else + fetchers.first.api_fetcher? + end + end + + def user_agent + @user_agent ||= begin + ruby = Bundler::RubyVersion.system + + agent = String.new("bundler/#{Bundler::VERSION}") + agent << " rubygems/#{Gem::VERSION}" + agent << " ruby/#{ruby.versions_string(ruby.versions)}" + agent << " (#{ruby.host})" + agent << " command/#{ARGV.first}" + + if ruby.engine != "ruby" + # engine_version raises on unknown engines + engine_version = begin + ruby.engine_versions + rescue RuntimeError + "???" + end + agent << " #{ruby.engine}/#{ruby.versions_string(engine_version)}" + end + + agent << " options/#{Bundler.settings.all.join(",")}" + + agent << " ci/#{cis.join(",")}" if cis.any? + + # add a random ID so we can consolidate runs server-side + agent << " " << SecureRandom.hex(8) + + # add any user agent strings set in the config + extra_ua = Bundler.settings[:user_agent] + agent << " " << extra_ua if extra_ua + + agent + end + end + + def fetchers + @fetchers ||= FETCHERS.map {|f| f.new(downloader, @remote, uri) } + end + + def http_proxy + return unless uri = connection.proxy_uri + uri.to_s + end + + def inspect + "#<#{self.class}:0x#{object_id} uri=#{uri}>" + end + + private + + FETCHERS = [CompactIndex, Dependency, Index].freeze + + def cis + env_cis = { + "TRAVIS" => "travis", + "CIRCLECI" => "circle", + "SEMAPHORE" => "semaphore", + "JENKINS_URL" => "jenkins", + "BUILDBOX" => "buildbox", + "GO_SERVER_URL" => "go", + "SNAP_CI" => "snap", + "GITLAB_CI" => "gitlab", + "GITHUB_ACTIONS" => "github", + "CI_NAME" => ENV["CI_NAME"], + "CI" => "ci", + } + env_cis.find_all {|env, _| ENV[env] }.map {|_, ci| ci } + end + + def connection + @connection ||= begin + needs_ssl = remote_uri.scheme == "https" || + Bundler.settings[:ssl_verify_mode] || + Bundler.settings[:ssl_client_cert] + raise SSLError if needs_ssl && !defined?(OpenSSL::SSL) + + con = PersistentHTTP.new :name => "bundler", :proxy => :ENV + if gem_proxy = Gem.configuration[:http_proxy] + con.proxy = Bundler::URI.parse(gem_proxy) if gem_proxy != :no_proxy + end + + if remote_uri.scheme == "https" + con.verify_mode = (Bundler.settings[:ssl_verify_mode] || + OpenSSL::SSL::VERIFY_PEER) + con.cert_store = bundler_cert_store + end + + ssl_client_cert = Bundler.settings[:ssl_client_cert] || + (Gem.configuration.ssl_client_cert if + Gem.configuration.respond_to?(:ssl_client_cert)) + if ssl_client_cert + pem = File.read(ssl_client_cert) + con.cert = OpenSSL::X509::Certificate.new(pem) + con.key = OpenSSL::PKey::RSA.new(pem) + end + + con.read_timeout = Fetcher.api_timeout + con.open_timeout = Fetcher.api_timeout + con.override_headers["User-Agent"] = user_agent + con.override_headers["X-Gemfile-Source"] = @remote.original_uri.to_s if @remote.original_uri + con + end + end + + # cached gem specification path, if one exists + def gemspec_cached_path(spec_file_name) + paths = Bundler.rubygems.spec_cache_dirs.map {|dir| File.join(dir, spec_file_name) } + paths.find {|path| File.file? path } + end + + HTTP_ERRORS = [ + Timeout::Error, EOFError, SocketError, Errno::ENETDOWN, Errno::ENETUNREACH, + Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN, + Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, + PersistentHTTP::Error, Zlib::BufError, Errno::EHOSTUNREACH + ].freeze + + def bundler_cert_store + store = OpenSSL::X509::Store.new + ssl_ca_cert = Bundler.settings[:ssl_ca_cert] || + (Gem.configuration.ssl_ca_cert if + Gem.configuration.respond_to?(:ssl_ca_cert)) + if ssl_ca_cert + if File.directory? ssl_ca_cert + store.add_path ssl_ca_cert + else + store.add_file ssl_ca_cert + end + else + store.set_default_paths + Gem::Request.get_cert_files.each {|c| store.add_file c } + end + store + end + + def remote_uri + @remote.uri + end + + def downloader + @downloader ||= Downloader.new(connection, self.class.redirect_limit) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/fetcher/base.rb b/games/FNaFB2/Ruby/stdlib/bundler/fetcher/base.rb new file mode 100644 index 0000000..62cc75a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/fetcher/base.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module Bundler + class Fetcher + class Base + attr_reader :downloader + attr_reader :display_uri + attr_reader :remote + + def initialize(downloader, remote, display_uri) + raise "Abstract class" if self.class == Base + @downloader = downloader + @remote = remote + @display_uri = display_uri + end + + def remote_uri + @remote.uri + end + + def fetch_uri + @fetch_uri ||= if remote_uri.host == "rubygems.org" + uri = remote_uri.dup + uri.host = "index.rubygems.org" + uri + else + remote_uri + end + end + + def available? + true + end + + def api_fetcher? + false + end + + private + + def log_specs(debug_msg) + if Bundler.ui.debug? + Bundler.ui.debug debug_msg + else + Bundler.ui.info ".", false + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/fetcher/compact_index.rb b/games/FNaFB2/Ruby/stdlib/bundler/fetcher/compact_index.rb new file mode 100644 index 0000000..b231765 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/fetcher/compact_index.rb @@ -0,0 +1,135 @@ +# frozen_string_literal: true + +require_relative "base" +require_relative "../worker" + +module Bundler + autoload :CompactIndexClient, File.expand_path("../compact_index_client", __dir__) + + class Fetcher + class CompactIndex < Base + def self.compact_index_request(method_name) + method = instance_method(method_name) + undef_method(method_name) + define_method(method_name) do |*args, &blk| + begin + method.bind(self).call(*args, &blk) + rescue NetworkDownError, CompactIndexClient::Updater::MisMatchedChecksumError => e + raise HTTPError, e.message + rescue AuthenticationRequiredError + # Fail since we got a 401 from the server. + raise + rescue HTTPError => e + Bundler.ui.trace(e) + nil + end + end + end + + def specs(gem_names) + specs_for_names(gem_names) + end + compact_index_request :specs + + def specs_for_names(gem_names) + gem_info = [] + complete_gems = [] + remaining_gems = gem_names.dup + + until remaining_gems.empty? + log_specs "Looking up gems #{remaining_gems.inspect}" + + deps = begin + parallel_compact_index_client.dependencies(remaining_gems) + rescue TooManyRequestsError + @bundle_worker.stop if @bundle_worker + @bundle_worker = nil # reset it. Not sure if necessary + serial_compact_index_client.dependencies(remaining_gems) + end + next_gems = deps.map {|d| d[3].map(&:first).flatten(1) }.flatten(1).uniq + deps.each {|dep| gem_info << dep } + complete_gems.concat(deps.map(&:first)).uniq! + remaining_gems = next_gems - complete_gems + end + @bundle_worker.stop if @bundle_worker + @bundle_worker = nil # reset it. Not sure if necessary + + gem_info + end + + def available? + unless SharedHelpers.md5_available? + Bundler.ui.debug("FIPS mode is enabled, bundler can't use the CompactIndex API") + return nil + end + if fetch_uri.scheme == "file" + Bundler.ui.debug("Using a local server, bundler won't use the CompactIndex API") + return false + end + # Read info file checksums out of /versions, so we can know if gems are up to date + compact_index_client.update_and_parse_checksums! + rescue CompactIndexClient::Updater::MisMatchedChecksumError => e + Bundler.ui.debug(e.message) + nil + end + compact_index_request :available? + + def api_fetcher? + true + end + + private + + def compact_index_client + @compact_index_client ||= + SharedHelpers.filesystem_access(cache_path) do + CompactIndexClient.new(cache_path, client_fetcher) + end + end + + def parallel_compact_index_client + compact_index_client.execution_mode = lambda do |inputs, &blk| + func = lambda {|object, _index| blk.call(object) } + worker = bundle_worker(func) + inputs.each {|input| worker.enq(input) } + inputs.map { worker.deq } + end + + compact_index_client + end + + def serial_compact_index_client + compact_index_client.sequential_execution_mode! + compact_index_client + end + + def bundle_worker(func = nil) + @bundle_worker ||= begin + worker_name = "Compact Index (#{display_uri.host})" + Bundler::Worker.new(Bundler.settings.processor_count, worker_name, func) + end + @bundle_worker.tap do |worker| + worker.instance_variable_set(:@func, func) if func + end + end + + def cache_path + Bundler.user_cache.join("compact_index", remote.cache_slug) + end + + def client_fetcher + ClientFetcher.new(self, Bundler.ui) + end + + ClientFetcher = Struct.new(:fetcher, :ui) do + def call(path, headers) + fetcher.downloader.fetch(fetcher.fetch_uri + path, headers) + rescue NetworkDownError => e + raise unless Bundler.feature_flag.allow_offline_install? && headers["If-None-Match"] + ui.warn "Using the cached data for the new index because of a network error: #{e}" + Net::HTTPNotModified.new(nil, nil, nil) + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/fetcher/dependency.rb b/games/FNaFB2/Ruby/stdlib/bundler/fetcher/dependency.rb new file mode 100644 index 0000000..c52c32f --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/fetcher/dependency.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +require_relative "base" +require "cgi" + +module Bundler + class Fetcher + class Dependency < Base + def available? + @available ||= fetch_uri.scheme != "file" && downloader.fetch(dependency_api_uri) + rescue NetworkDownError => e + raise HTTPError, e.message + rescue AuthenticationRequiredError + # Fail since we got a 401 from the server. + raise + rescue HTTPError + false + end + + def api_fetcher? + true + end + + def specs(gem_names, full_dependency_list = [], last_spec_list = []) + query_list = gem_names.uniq - full_dependency_list + + log_specs "Query List: #{query_list.inspect}" + + return last_spec_list if query_list.empty? + + spec_list, deps_list = Bundler::Retry.new("dependency api", FAIL_ERRORS).attempts do + dependency_specs(query_list) + end + + returned_gems = spec_list.map(&:first).uniq + specs(deps_list, full_dependency_list + returned_gems, spec_list + last_spec_list) + rescue MarshalError + Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over + Bundler.ui.debug "could not fetch from the dependency API, trying the full index" + nil + rescue HTTPError, GemspecError + Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over + Bundler.ui.debug "could not fetch from the dependency API\nit's suggested to retry using the full index via `bundle install --full-index`" + nil + end + + def dependency_specs(gem_names) + Bundler.ui.debug "Query Gemcutter Dependency Endpoint API: #{gem_names.join(",")}" + + gem_list = unmarshalled_dep_gems(gem_names) + get_formatted_specs_and_deps(gem_list) + end + + def unmarshalled_dep_gems(gem_names) + gem_list = [] + gem_names.each_slice(Source::Rubygems::API_REQUEST_SIZE) do |names| + marshalled_deps = downloader.fetch(dependency_api_uri(names)).body + gem_list.concat(Bundler.load_marshal(marshalled_deps)) + end + gem_list + end + + def get_formatted_specs_and_deps(gem_list) + deps_list = [] + spec_list = [] + + gem_list.each do |s| + deps_list.concat(s[:dependencies].map(&:first)) + deps = s[:dependencies].map {|n, d| [n, d.split(", ")] } + spec_list.push([s[:name], s[:number], s[:platform], deps]) + end + [spec_list, deps_list] + end + + def dependency_api_uri(gem_names = []) + uri = fetch_uri + "api/v1/dependencies" + uri.query = "gems=#{CGI.escape(gem_names.sort.join(","))}" if gem_names.any? + uri + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/fetcher/downloader.rb b/games/FNaFB2/Ruby/stdlib/bundler/fetcher/downloader.rb new file mode 100644 index 0000000..f2aad3a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/fetcher/downloader.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +module Bundler + class Fetcher + class Downloader + attr_reader :connection + attr_reader :redirect_limit + + def initialize(connection, redirect_limit) + @connection = connection + @redirect_limit = redirect_limit + end + + def fetch(uri, headers = {}, counter = 0) + raise HTTPError, "Too many redirects" if counter >= redirect_limit + + filtered_uri = URICredentialsFilter.credential_filtered_uri(uri) + + response = request(uri, headers) + Bundler.ui.debug("HTTP #{response.code} #{response.message} #{filtered_uri}") + + case response + when Net::HTTPSuccess, Net::HTTPNotModified + response + when Net::HTTPRedirection + new_uri = Bundler::URI.parse(response["location"]) + if new_uri.host == uri.host + new_uri.user = uri.user + new_uri.password = uri.password + end + fetch(new_uri, headers, counter + 1) + when Net::HTTPRequestedRangeNotSatisfiable + new_headers = headers.dup + new_headers.delete("Range") + new_headers["Accept-Encoding"] = "gzip" + fetch(uri, new_headers) + when Net::HTTPRequestEntityTooLarge + raise FallbackError, response.body + when Net::HTTPTooManyRequests + raise TooManyRequestsError, response.body + when Net::HTTPUnauthorized + raise BadAuthenticationError, uri.host if uri.userinfo + raise AuthenticationRequiredError, uri.host + when Net::HTTPNotFound + raise FallbackError, "Net::HTTPNotFound: #{filtered_uri}" + else + raise HTTPError, "#{response.class}#{": #{response.body}" unless response.body.empty?}" + end + end + + def request(uri, headers) + validate_uri_scheme!(uri) + + filtered_uri = URICredentialsFilter.credential_filtered_uri(uri) + + Bundler.ui.debug "HTTP GET #{filtered_uri}" + req = Net::HTTP::Get.new uri.request_uri, headers + if uri.user + user = CGI.unescape(uri.user) + password = uri.password ? CGI.unescape(uri.password) : nil + req.basic_auth(user, password) + end + connection.request(uri, req) + rescue NoMethodError => e + raise unless ["undefined method", "use_ssl="].all? {|snippet| e.message.include? snippet } + raise LoadError.new("cannot load such file -- openssl") + rescue OpenSSL::SSL::SSLError + raise CertificateFailureError.new(uri) + rescue *HTTP_ERRORS => e + Bundler.ui.trace e + if e.is_a?(SocketError) || e.message =~ /host down:/ + raise NetworkDownError, "Could not reach host #{uri.host}. Check your network " \ + "connection and try again." + else + raise HTTPError, "Network error while fetching #{filtered_uri}" \ + " (#{e})" + end + end + + private + + def validate_uri_scheme!(uri) + return if uri.scheme =~ /\Ahttps?\z/ + raise InvalidOption, + "The request uri `#{uri}` has an invalid scheme (`#{uri.scheme}`). " \ + "Did you mean `http` or `https`?" + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/fetcher/index.rb b/games/FNaFB2/Ruby/stdlib/bundler/fetcher/index.rb new file mode 100644 index 0000000..6bb9fcc --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/fetcher/index.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require_relative "base" + +module Bundler + class Fetcher + class Index < Base + def specs(_gem_names) + Bundler.rubygems.fetch_all_remote_specs(remote) + rescue Gem::RemoteFetcher::FetchError => e + case e.message + when /certificate verify failed/ + raise CertificateFailureError.new(display_uri) + when /401/ + raise BadAuthenticationError, remote_uri if remote_uri.userinfo + raise AuthenticationRequiredError, remote_uri + when /403/ + raise BadAuthenticationError, remote_uri if remote_uri.userinfo + raise AuthenticationRequiredError, remote_uri + else + raise HTTPError, "Could not fetch specs from #{display_uri} due to underlying error <#{e.message}>" + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/friendly_errors.rb b/games/FNaFB2/Ruby/stdlib/bundler/friendly_errors.rb new file mode 100644 index 0000000..d0d2a66 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/friendly_errors.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +require_relative "vendored_thor" + +module Bundler + module FriendlyErrors + module_function + + def enable! + @disabled = false + end + + def disabled? + @disabled + end + + def disable! + @disabled = true + end + + def log_error(error) + case error + when YamlSyntaxError + Bundler.ui.error error.message + Bundler.ui.trace error.orig_exception + when Dsl::DSLError, GemspecError + Bundler.ui.error error.message + when GemRequireError + Bundler.ui.error error.message + Bundler.ui.trace error.orig_exception + when BundlerError + if Bundler.ui.debug? + Bundler.ui.trace error + else + Bundler.ui.error error.message, :wrap => true + end + when Thor::Error + Bundler.ui.error error.message + when LoadError + raise error unless error.message =~ /cannot load such file -- openssl|openssl.so|libcrypto.so/ + Bundler.ui.error "\nCould not load OpenSSL. #{error.class}: #{error}\n#{error.backtrace.join("\n ")}" + when Interrupt + Bundler.ui.error "\nQuitting..." + Bundler.ui.trace error + when Gem::InvalidSpecificationException + Bundler.ui.error error.message, :wrap => true + when SystemExit + when *[defined?(Java::JavaLang::OutOfMemoryError) && Java::JavaLang::OutOfMemoryError].compact + Bundler.ui.error "\nYour JVM has run out of memory, and Bundler cannot continue. " \ + "You can decrease the amount of memory Bundler needs by removing gems from your Gemfile, " \ + "especially large gems. (Gems can be as large as hundreds of megabytes, and Bundler has to read those files!). " \ + "Alternatively, you can increase the amount of memory the JVM is able to use by running Bundler with jruby -J-Xmx1024m -S bundle (JRuby defaults to 500MB)." + else request_issue_report_for(error) + end + end + + def exit_status(error) + case error + when BundlerError then error.status_code + when Thor::Error then 15 + when SystemExit then error.status + else 1 + end + end + + def request_issue_report_for(e) + Bundler.ui.error <<-EOS.gsub(/^ {8}/, ""), nil, nil + --- ERROR REPORT TEMPLATE ------------------------------------------------------- + + ``` + #{exception_message(e)} + ``` + + #{Bundler::Env.report} + --- TEMPLATE END ---------------------------------------------------------------- + + EOS + + Bundler.ui.error "Unfortunately, an unexpected error occurred, and Bundler cannot continue." + + Bundler.ui.error <<-EOS.gsub(/^ {8}/, ""), nil, :yellow + + First, try this link to see if there are any existing issue reports for this error: + #{issues_url(e)} + + If there aren't any reports for this error yet, please fill in the new issue form located at #{new_issue_url}, and copy and paste the report template above in there. + EOS + end + + def exception_message(error) + message = serialized_exception_for(error) + cause = error.cause + return message unless cause + + message + serialized_exception_for(cause) + end + + def serialized_exception_for(e) + <<-EOS.gsub(/^ {8}/, "") + #{e.class}: #{e.message} + #{e.backtrace && e.backtrace.join("\n ").chomp} + EOS + end + + def issues_url(exception) + message = exception.message.lines.first.tr(":", " ").chomp + message = message.split("-").first if exception.is_a?(Errno) + require "cgi" + "https://github.com/rubygems/rubygems/search?q=" \ + "#{CGI.escape(message)}&type=Issues" + end + + def new_issue_url + "https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md" + end + end + + def self.with_friendly_errors + FriendlyErrors.enable! + yield + rescue SignalException + raise + rescue Exception => e # rubocop:disable Lint/RescueException + raise if FriendlyErrors.disabled? + + FriendlyErrors.log_error(e) + exit FriendlyErrors.exit_status(e) + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/gem_helper.rb b/games/FNaFB2/Ruby/stdlib/bundler/gem_helper.rb new file mode 100644 index 0000000..0bbd2d9 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/gem_helper.rb @@ -0,0 +1,238 @@ +# frozen_string_literal: true + +require_relative "../bundler" +require "shellwords" + +module Bundler + class GemHelper + include Rake::DSL if defined? Rake::DSL + + class << self + # set when install'd. + attr_accessor :instance + + def install_tasks(opts = {}) + new(opts[:dir], opts[:name]).install + end + + def tag_prefix=(prefix) + instance.tag_prefix = prefix + end + + def gemspec(&block) + gemspec = instance.gemspec + block.call(gemspec) if block + gemspec + end + end + + attr_reader :spec_path, :base, :gemspec + + attr_writer :tag_prefix + + def initialize(base = nil, name = nil) + @base = File.expand_path(base || SharedHelpers.pwd) + gemspecs = name ? [File.join(@base, "#{name}.gemspec")] : Gem::Util.glob_files_in_dir("{,*}.gemspec", @base) + raise "Unable to determine name from existing gemspec. Use :name => 'gemname' in #install_tasks to manually set it." unless gemspecs.size == 1 + @spec_path = gemspecs.first + @gemspec = Bundler.load_gemspec(@spec_path) + @tag_prefix = "" + end + + def install + built_gem_path = nil + + desc "Build #{name}-#{version}.gem into the pkg directory." + task "build" do + built_gem_path = build_gem + end + + desc "Generate SHA512 checksum if #{name}-#{version}.gem into the checksums directory." + task "build:checksum" => "build" do + build_checksum(built_gem_path) + end + + desc "Build and install #{name}-#{version}.gem into system gems." + task "install" => "build" do + install_gem(built_gem_path) + end + + desc "Build and install #{name}-#{version}.gem into system gems without network access." + task "install:local" => "build" do + install_gem(built_gem_path, :local) + end + + desc "Create tag #{version_tag} and build and push #{name}-#{version}.gem to #{gem_push_host}\n" \ + "To prevent publishing in RubyGems use `gem_push=no rake release`" + task "release", [:remote] => ["build", "release:guard_clean", + "release:source_control_push", "release:rubygem_push"] do + end + + task "release:guard_clean" do + guard_clean + end + + task "release:source_control_push", [:remote] do |_, args| + tag_version { git_push(args[:remote]) } unless already_tagged? + end + + task "release:rubygem_push" => "build" do + rubygem_push(built_gem_path) if gem_push? + end + + GemHelper.instance = self + end + + def build_gem + file_name = nil + sh([*gem_command, "build", "-V", spec_path]) do + file_name = File.basename(built_gem_path) + SharedHelpers.filesystem_access(File.join(base, "pkg")) {|p| FileUtils.mkdir_p(p) } + FileUtils.mv(built_gem_path, "pkg") + Bundler.ui.confirm "#{name} #{version} built to pkg/#{file_name}." + end + File.join(base, "pkg", file_name) + end + + def install_gem(built_gem_path = nil, local = false) + built_gem_path ||= build_gem + cmd = [*gem_command, "install", built_gem_path.to_s] + cmd << "--local" if local + sh(cmd) + Bundler.ui.confirm "#{name} (#{version}) installed." + end + + def build_checksum(built_gem_path = nil) + built_gem_path ||= build_gem + SharedHelpers.filesystem_access(File.join(base, "checksums")) {|p| FileUtils.mkdir_p(p) } + file_name = "#{File.basename(built_gem_path)}.sha512" + require "digest/sha2" + checksum = ::Digest::SHA512.file(built_gem_path).hexdigest + target = File.join(base, "checksums", file_name) + File.write(target, checksum + "\n") + Bundler.ui.confirm "#{name} #{version} checksum written to checksums/#{file_name}." + end + + protected + + def rubygem_push(path) + cmd = [*gem_command, "push", path] + cmd << "--key" << gem_key if gem_key + cmd << "--host" << allowed_push_host if allowed_push_host + sh_with_input(cmd) + Bundler.ui.confirm "Pushed #{name} #{version} to #{gem_push_host}" + end + + def built_gem_path + Gem::Util.glob_files_in_dir("#{name}-*.gem", base).sort_by {|f| File.mtime(f) }.last + end + + def git_push(remote = nil) + remote ||= default_remote + sh("git push #{remote} refs/heads/#{current_branch}".shellsplit) + sh("git push #{remote} refs/tags/#{version_tag}".shellsplit) + Bundler.ui.confirm "Pushed git commits and release tag." + end + + def default_remote + remote_for_branch, status = sh_with_status(%W[git config --get branch.#{current_branch}.remote]) + return "origin" unless status.success? + + remote_for_branch.strip + end + + def current_branch + # We can replace this with `git branch --show-current` once we drop support for git < 2.22.0 + sh(%w[git rev-parse --abbrev-ref HEAD]).gsub(%r{\Aheads/}, "").strip + end + + def allowed_push_host + @gemspec.metadata["allowed_push_host"] if @gemspec.respond_to?(:metadata) + end + + def gem_push_host + env_rubygems_host = ENV["RUBYGEMS_HOST"] + env_rubygems_host = nil if + env_rubygems_host && env_rubygems_host.empty? + + allowed_push_host || env_rubygems_host || "rubygems.org" + end + + def already_tagged? + return false unless sh(%w[git tag]).split(/\n/).include?(version_tag) + Bundler.ui.confirm "Tag #{version_tag} has already been created." + true + end + + def guard_clean + clean? && committed? || raise("There are files that need to be committed first.") + end + + def clean? + sh_with_status(%w[git diff --exit-code])[1].success? + end + + def committed? + sh_with_status(%w[git diff-index --quiet --cached HEAD])[1].success? + end + + def tag_version + sh %W[git tag -m Version\ #{version} #{version_tag}] + Bundler.ui.confirm "Tagged #{version_tag}." + yield if block_given? + rescue RuntimeError + Bundler.ui.error "Untagging #{version_tag} due to error." + sh_with_status %W[git tag -d #{version_tag}] + raise + end + + def version + gemspec.version + end + + def version_tag + "#{@tag_prefix}v#{version}" + end + + def name + gemspec.name + end + + def sh_with_input(cmd) + Bundler.ui.debug(cmd) + SharedHelpers.chdir(base) do + abort unless Kernel.system(*cmd) + end + end + + def sh(cmd, &block) + out, status = sh_with_status(cmd, &block) + unless status.success? + raise("Running `#{cmd.shelljoin}` failed with the following output:\n\n#{out}\n") + end + out + end + + def sh_with_status(cmd, &block) + Bundler.ui.debug(cmd) + SharedHelpers.chdir(base) do + outbuf = IO.popen(cmd, :err => [:child, :out], &:read) + status = $? + block.call(outbuf) if status.success? && block + [outbuf, status] + end + end + + def gem_key + Bundler.settings["gem.push_key"].to_s.downcase if Bundler.settings["gem.push_key"] + end + + def gem_push? + !%w[n no nil false off 0].include?(ENV["gem_push"].to_s.downcase) + end + + def gem_command + ENV["GEM_COMMAND"]&.shellsplit || ["gem"] + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/gem_helpers.rb b/games/FNaFB2/Ruby/stdlib/bundler/gem_helpers.rb new file mode 100644 index 0000000..2e6d788 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/gem_helpers.rb @@ -0,0 +1,117 @@ +# frozen_string_literal: true + +module Bundler + module GemHelpers + GENERIC_CACHE = { Gem::Platform::RUBY => Gem::Platform::RUBY } # rubocop:disable Style/MutableConstant + GENERICS = [ + [Gem::Platform.new("java"), Gem::Platform.new("java")], + [Gem::Platform.new("mswin32"), Gem::Platform.new("mswin32")], + [Gem::Platform.new("mswin64"), Gem::Platform.new("mswin64")], + [Gem::Platform.new("universal-mingw32"), Gem::Platform.new("universal-mingw32")], + [Gem::Platform.new("x64-mingw32"), Gem::Platform.new("x64-mingw32")], + [Gem::Platform.new("x86_64-mingw32"), Gem::Platform.new("x64-mingw32")], + [Gem::Platform.new("x64-mingw-ucrt"), Gem::Platform.new("x64-mingw-ucrt")], + [Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")], + ].freeze + + def generic(p) + GENERIC_CACHE[p] ||= begin + _, found = GENERICS.find do |match, _generic| + p.os == match.os && (!match.cpu || p.cpu == match.cpu) + end + found || Gem::Platform::RUBY + end + end + module_function :generic + + def generic_local_platform + generic(local_platform) + end + module_function :generic_local_platform + + def local_platform + Bundler.local_platform + end + module_function :local_platform + + def platform_specificity_match(spec_platform, user_platform) + spec_platform = Gem::Platform.new(spec_platform) + + PlatformMatch.specificity_score(spec_platform, user_platform) + end + module_function :platform_specificity_match + + def select_best_platform_match(specs, platform) + matching = specs.select {|spec| spec.match_platform(platform) } + + sort_best_platform_match(matching, platform) + end + module_function :select_best_platform_match + + def sort_best_platform_match(matching, platform) + exact = matching.select {|spec| spec.platform == platform } + return exact if exact.any? + + sorted_matching = matching.sort_by {|spec| platform_specificity_match(spec.platform, platform) } + exemplary_spec = sorted_matching.first + + sorted_matching.take_while {|spec| same_specificity(platform, spec, exemplary_spec) && same_deps(spec, exemplary_spec) } + end + module_function :sort_best_platform_match + + class PlatformMatch + def self.specificity_score(spec_platform, user_platform) + return -1 if spec_platform == user_platform + return 1_000_000 if spec_platform.nil? || spec_platform == Gem::Platform::RUBY || user_platform == Gem::Platform::RUBY + + os_match(spec_platform, user_platform) + + cpu_match(spec_platform, user_platform) * 10 + + platform_version_match(spec_platform, user_platform) * 100 + end + + def self.os_match(spec_platform, user_platform) + if spec_platform.os == user_platform.os + 0 + else + 1 + end + end + + def self.cpu_match(spec_platform, user_platform) + if spec_platform.cpu == user_platform.cpu + 0 + elsif spec_platform.cpu == "arm" && user_platform.cpu.to_s.start_with?("arm") + 0 + elsif spec_platform.cpu.nil? || spec_platform.cpu == "universal" + 1 + else + 2 + end + end + + def self.platform_version_match(spec_platform, user_platform) + if spec_platform.version == user_platform.version + 0 + elsif spec_platform.version.nil? + 1 + else + 2 + end + end + end + + def same_specificity(platform, spec, exemplary_spec) + platform_specificity_match(spec.platform, platform) == platform_specificity_match(exemplary_spec.platform, platform) + end + module_function :same_specificity + + def same_deps(spec, exemplary_spec) + same_runtime_deps = spec.dependencies.sort == exemplary_spec.dependencies.sort + return same_runtime_deps unless spec.is_a?(Gem::Specification) && exemplary_spec.is_a?(Gem::Specification) + + same_metadata_deps = spec.required_ruby_version == exemplary_spec.required_ruby_version && spec.required_rubygems_version == exemplary_spec.required_rubygems_version + same_runtime_deps && same_metadata_deps + end + module_function :same_deps + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/gem_tasks.rb b/games/FNaFB2/Ruby/stdlib/bundler/gem_tasks.rb new file mode 100644 index 0000000..bc725d3 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/gem_tasks.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require "rake/clean" +CLOBBER.include "pkg" + +require_relative "gem_helper" +Bundler::GemHelper.install_tasks diff --git a/games/FNaFB2/Ruby/stdlib/bundler/gem_version_promoter.rb b/games/FNaFB2/Ruby/stdlib/bundler/gem_version_promoter.rb new file mode 100644 index 0000000..ee2c38a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/gem_version_promoter.rb @@ -0,0 +1,179 @@ +# frozen_string_literal: true + +module Bundler + # This class contains all of the logic for determining the next version of a + # Gem to update to based on the requested level (patch, minor, major). + # Primarily designed to work with Resolver which will provide it the list of + # available dependency versions as found in its index, before returning it to + # to the resolution engine to select the best version. + class GemVersionPromoter + DEBUG = ENV["BUNDLER_DEBUG_RESOLVER"] || ENV["DEBUG_RESOLVER"] + + attr_reader :level, :locked_specs, :unlock_gems + + # By default, strict is false, meaning every available version of a gem + # is returned from sort_versions. The order gives preference to the + # requested level (:patch, :minor, :major) but in complicated requirement + # cases some gems will by necessity by promoted past the requested level, + # or even reverted to older versions. + # + # If strict is set to true, the results from sort_versions will be + # truncated, eliminating any version outside the current level scope. + # This can lead to unexpected outcomes or even VersionConflict exceptions + # that report a version of a gem not existing for versions that indeed do + # existing in the referenced source. + attr_accessor :strict + + attr_accessor :prerelease_specified + + # Given a list of locked_specs and a list of gems to unlock creates a + # GemVersionPromoter instance. + # + # @param locked_specs [SpecSet] All current locked specs. Unlike Definition + # where this list is empty if all gems are being updated, this should + # always be populated for all gems so this class can properly function. + # @param unlock_gems [String] List of gem names being unlocked. If empty, + # all gems will be considered unlocked. + # @return [GemVersionPromoter] + def initialize(locked_specs = SpecSet.new([]), unlock_gems = []) + @level = :major + @strict = false + @locked_specs = locked_specs + @unlock_gems = unlock_gems + @sort_versions = {} + @prerelease_specified = {} + end + + # @param value [Symbol] One of three Symbols: :major, :minor or :patch. + def level=(value) + v = case value + when String, Symbol + value.to_sym + end + + raise ArgumentError, "Unexpected level #{v}. Must be :major, :minor or :patch" unless [:major, :minor, :patch].include?(v) + @level = v + end + + # Given a Dependency and an Array of Specifications of available versions for a + # gem, this method will return the Array of Specifications sorted (and possibly + # truncated if strict is true) in an order to give preference to the current + # level (:major, :minor or :patch) when resolution is deciding what versions + # best resolve all dependencies in the bundle. + # @param dep [Dependency] The Dependency of the gem. + # @param spec_groups [Specification] An array of Specifications for the same gem + # named in the @dep param. + # @return [Specification] A new instance of the Specification Array sorted and + # possibly filtered. + def sort_versions(dep, spec_groups) + @sort_versions[dep] ||= begin + gem_name = dep.name + + # An Array per version returned, different entries for different platforms. + # We only need the version here so it's ok to hard code this to the first instance. + locked_spec = locked_specs[gem_name].first + + if strict + filter_dep_specs(spec_groups, locked_spec) + else + sort_dep_specs(spec_groups, locked_spec) + end + end + end + + def reset + @sort_versions = {} + end + + # @return [bool] Convenience method for testing value of level variable. + def major? + level == :major + end + + # @return [bool] Convenience method for testing value of level variable. + def minor? + level == :minor + end + + private + + def filter_dep_specs(spec_groups, locked_spec) + res = spec_groups.select do |spec_group| + if locked_spec && !major? + gsv = spec_group.version + lsv = locked_spec.version + + must_match = minor? ? [0] : [0, 1] + + matches = must_match.map {|idx| gsv.segments[idx] == lsv.segments[idx] } + matches.uniq == [true] ? (gsv >= lsv) : false + else + true + end + end + + sort_dep_specs(res, locked_spec) + end + + def sort_dep_specs(spec_groups, locked_spec) + @locked_version = locked_spec&.version + @gem_name = locked_spec&.name + + result = spec_groups.sort do |a, b| + @a_ver = a.version + @b_ver = b.version + + unless @gem_name && @prerelease_specified[@gem_name] + a_pre = @a_ver.prerelease? + b_pre = @b_ver.prerelease? + + next -1 if a_pre && !b_pre + next 1 if b_pre && !a_pre + end + + if major? + @a_ver <=> @b_ver + elsif either_version_older_than_locked + @a_ver <=> @b_ver + elsif segments_do_not_match(:major) + @b_ver <=> @a_ver + elsif !minor? && segments_do_not_match(:minor) + @b_ver <=> @a_ver + else + @a_ver <=> @b_ver + end + end + post_sort(result) + end + + def either_version_older_than_locked + @locked_version && (@a_ver < @locked_version || @b_ver < @locked_version) + end + + def segments_do_not_match(level) + index = [:major, :minor].index(level) + @a_ver.segments[index] != @b_ver.segments[index] + end + + def unlocking_gem? + unlock_gems.empty? || (@gem_name && unlock_gems.include?(@gem_name)) + end + + # Specific version moves can't always reliably be done during sorting + # as not all elements are compared against each other. + def post_sort(result) + # default :major behavior in Bundler does not do this + return result if major? + if unlocking_gem? || @locked_version.nil? + result + else + move_version_to_end(result, @locked_version) + end + end + + def move_version_to_end(result, version) + move, keep = result.partition {|s| s.version.to_s == version.to_s } + keep.concat(move) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/graph.rb b/games/FNaFB2/Ruby/stdlib/bundler/graph.rb new file mode 100644 index 0000000..8f52e2f --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/graph.rb @@ -0,0 +1,152 @@ +# frozen_string_literal: true + +require "set" +module Bundler + class Graph + GRAPH_NAME = :Gemfile + + def initialize(env, output_file, show_version = false, show_requirements = false, output_format = "png", without = []) + @env = env + @output_file = output_file + @show_version = show_version + @show_requirements = show_requirements + @output_format = output_format + @without_groups = without.map(&:to_sym) + + @groups = [] + @relations = Hash.new {|h, k| h[k] = Set.new } + @node_options = {} + @edge_options = {} + + _populate_relations + end + + attr_reader :groups, :relations, :node_options, :edge_options, :output_file, :output_format + + def viz + GraphVizClient.new(self).run + end + + private + + def _populate_relations + parent_dependencies = _groups.values.to_set.flatten + loop do + break if parent_dependencies.empty? + + tmp = Set.new + parent_dependencies.each do |dependency| + child_dependencies = spec_for_dependency(dependency).runtime_dependencies.to_set + @relations[dependency.name] += child_dependencies.map(&:name).to_set + tmp += child_dependencies + + @node_options[dependency.name] = _make_label(dependency, :node) + child_dependencies.each do |c_dependency| + @edge_options["#{dependency.name}_#{c_dependency.name}"] = _make_label(c_dependency, :edge) + end + end + parent_dependencies = tmp + end + end + + def _groups + relations = Hash.new {|h, k| h[k] = Set.new } + @env.current_dependencies.each do |dependency| + dependency.groups.each do |group| + next if @without_groups.include?(group) + + relations[group.to_s].add(dependency) + @relations[group.to_s].add(dependency.name) + + @node_options[group.to_s] ||= _make_label(group, :node) + @edge_options["#{group}_#{dependency.name}"] = _make_label(dependency, :edge) + end + end + @groups = relations.keys + relations + end + + def _make_label(symbol_or_string_or_dependency, element_type) + case element_type.to_sym + when :node + if symbol_or_string_or_dependency.is_a?(Gem::Dependency) + label = symbol_or_string_or_dependency.name.dup + label << "\n#{spec_for_dependency(symbol_or_string_or_dependency).version}" if @show_version + else + label = symbol_or_string_or_dependency.to_s + end + when :edge + label = nil + if symbol_or_string_or_dependency.respond_to?(:requirements_list) && @show_requirements + tmp = symbol_or_string_or_dependency.requirements_list.join(", ") + label = tmp if tmp != ">= 0" + end + else + raise ArgumentError, "2nd argument is invalid" + end + label.nil? ? {} : { :label => label } + end + + def spec_for_dependency(dependency) + @env.requested_specs.find {|s| s.name == dependency.name } + end + + class GraphVizClient + def initialize(graph_instance) + @graph_name = graph_instance.class::GRAPH_NAME + @groups = graph_instance.groups + @relations = graph_instance.relations + @node_options = graph_instance.node_options + @edge_options = graph_instance.edge_options + @output_file = graph_instance.output_file + @output_format = graph_instance.output_format + end + + def g + @g ||= ::GraphViz.digraph(@graph_name, :concentrate => true, :normalize => true, :nodesep => 0.55) do |g| + g.edge[:weight] = 2 + g.edge[:fontname] = g.node[:fontname] = "Arial, Helvetica, SansSerif" + g.edge[:fontsize] = 12 + end + end + + def run + @groups.each do |group| + g.add_nodes( + group, { + :style => "filled", + :fillcolor => "#B9B9D5", + :shape => "box3d", + :fontsize => 16, + }.merge(@node_options[group]) + ) + end + + @relations.each do |parent, children| + children.each do |child| + if @groups.include?(parent) + g.add_nodes(child, { :style => "filled", :fillcolor => "#B9B9D5" }.merge(@node_options[child])) + g.add_edges(parent, child, { :constraint => false }.merge(@edge_options["#{parent}_#{child}"])) + else + g.add_nodes(child, @node_options[child]) + g.add_edges(parent, child, @edge_options["#{parent}_#{child}"]) + end + end + end + + if @output_format.to_s == "debug" + $stdout.puts g.output :none => String + Bundler.ui.info "debugging bundle viz..." + else + begin + g.output @output_format.to_sym => "#{@output_file}.#{@output_format}" + Bundler.ui.info "#{@output_file}.#{@output_format}" + rescue ArgumentError => e + warn "Unsupported output format. See Ruby-Graphviz/lib/graphviz/constants.rb" + raise e + end + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/index.rb b/games/FNaFB2/Ruby/stdlib/bundler/index.rb new file mode 100644 index 0000000..ed16c90 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/index.rb @@ -0,0 +1,183 @@ +# frozen_string_literal: true + +module Bundler + class Index + include Enumerable + + def self.build + i = new + yield i + i + end + + attr_reader :specs, :all_specs, :sources + protected :specs, :all_specs + + RUBY = "ruby".freeze + NULL = "\0".freeze + + def initialize + @sources = [] + @cache = {} + @specs = Hash.new {|h, k| h[k] = {} } + @all_specs = Hash.new {|h, k| h[k] = EMPTY_SEARCH } + end + + def initialize_copy(o) + @sources = o.sources.dup + @cache = {} + @specs = Hash.new {|h, k| h[k] = {} } + @all_specs = Hash.new {|h, k| h[k] = EMPTY_SEARCH } + + o.specs.each do |name, hash| + @specs[name] = hash.dup + end + o.all_specs.each do |name, array| + @all_specs[name] = array.dup + end + end + + def inspect + "#<#{self.class}:0x#{object_id} sources=#{sources.map(&:inspect)} specs.size=#{specs.size}>" + end + + def empty? + each { return false } + true + end + + def search_all(name) + all_matches = local_search(name) + @all_specs[name] + @sources.each do |source| + all_matches.concat(source.search_all(name)) + end + all_matches + end + + # Search this index's specs, and any source indexes that this index knows + # about, returning all of the results. + def search(query) + results = local_search(query) + return results unless @sources.any? + + @sources.each do |source| + results.concat(source.search(query)) + end + results.uniq(&:full_name) + end + + def local_search(query) + case query + when Gem::Specification, RemoteSpecification, LazySpecification, EndpointSpecification then search_by_spec(query) + when String then specs_by_name(query) + when Gem::Dependency then search_by_dependency(query) + else + raise "You can't search for a #{query.inspect}." + end + end + + alias_method :[], :search + + def <<(spec) + @specs[spec.name][spec.full_name] = spec + spec + end + + def each(&blk) + return enum_for(:each) unless blk + specs.values.each do |spec_sets| + spec_sets.values.each(&blk) + end + sources.each {|s| s.each(&blk) } + self + end + + def spec_names + names = specs.keys + sources.map(&:spec_names) + names.uniq! + names + end + + def unmet_dependency_names + dependency_names.select do |name| + search(name).empty? + end + end + + def dependency_names + names = [] + each do |spec| + spec.dependencies.each do |dep| + next if dep.type == :development + names << dep.name + end + end + names.uniq + end + + def use(other, override_dupes = false) + return unless other + other.each do |s| + if (dupes = search_by_spec(s)) && !dupes.empty? + # safe to << since it's a new array when it has contents + @all_specs[s.name] = dupes << s + next unless override_dupes + end + self << s + end + self + end + + def size + @sources.inject(@specs.size) do |size, source| + size += source.size + end + end + + # Whether all the specs in self are in other + # TODO: rename to #include? + def ==(other) + all? do |spec| + other_spec = other[spec].first + other_spec && dependencies_eql?(spec, other_spec) && spec.source == other_spec.source + end + end + + def dependencies_eql?(spec, other_spec) + deps = spec.dependencies.select {|d| d.type != :development } + other_deps = other_spec.dependencies.select {|d| d.type != :development } + deps.sort == other_deps.sort + end + + def add_source(index) + raise ArgumentError, "Source must be an index, not #{index.class}" unless index.is_a?(Index) + @sources << index + @sources.uniq! # need to use uniq! here instead of checking for the item before adding + end + + private + + def specs_by_name(name) + @specs[name].values + end + + def search_by_dependency(dependency) + @cache[dependency] ||= begin + specs = specs_by_name(dependency.name) + found = specs.select do |spec| + next true if spec.source.is_a?(Source::Gemspec) + dependency.matches_spec?(spec) + end + + found + end + end + + EMPTY_SEARCH = [].freeze + + def search_by_spec(spec) + spec = @specs[spec.name][spec.full_name] + spec ? [spec] : EMPTY_SEARCH + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/injector.rb b/games/FNaFB2/Ruby/stdlib/bundler/injector.rb new file mode 100644 index 0000000..81465ce --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/injector.rb @@ -0,0 +1,287 @@ +# frozen_string_literal: true + +module Bundler + class Injector + INJECTED_GEMS = "injected gems".freeze + + def self.inject(new_deps, options = {}) + injector = new(new_deps, options) + injector.inject(Bundler.default_gemfile, Bundler.default_lockfile) + end + + def self.remove(gems, options = {}) + injector = new(gems, options) + injector.remove(Bundler.default_gemfile, Bundler.default_lockfile) + end + + def initialize(deps, options = {}) + @deps = deps + @options = options + end + + # @param [Pathname] gemfile_path The Gemfile in which to inject the new dependency. + # @param [Pathname] lockfile_path The lockfile in which to inject the new dependency. + # @return [Array] + def inject(gemfile_path, lockfile_path) + if Bundler.frozen_bundle? + # ensure the lock and Gemfile are synced + Bundler.definition.ensure_equivalent_gemfile_and_lockfile(true) + end + + # temporarily unfreeze + Bundler.settings.temporary(:deployment => false, :frozen => false) do + # evaluate the Gemfile we have now + builder = Dsl.new + builder.eval_gemfile(gemfile_path) + + # don't inject any gems that are already in the Gemfile + @deps -= builder.dependencies + + # add new deps to the end of the in-memory Gemfile + # Set conservative versioning to false because + # we want to let the resolver resolve the version first + builder.eval_gemfile(INJECTED_GEMS, build_gem_lines(false)) if @deps.any? + + # resolve to see if the new deps broke anything + @definition = builder.to_definition(lockfile_path, {}) + @definition.resolve_remotely! + + # since nothing broke, we can add those gems to the gemfile + append_to(gemfile_path, build_gem_lines(@options[:conservative_versioning])) if @deps.any? + + # since we resolved successfully, write out the lockfile + @definition.lock(Bundler.default_lockfile) + + # invalidate the cached Bundler.definition + Bundler.reset_paths! + + # return an array of the deps that we added + @deps + end + end + + # @param [Pathname] gemfile_path The Gemfile from which to remove dependencies. + # @param [Pathname] lockfile_path The lockfile from which to remove dependencies. + # @return [Array] + def remove(gemfile_path, lockfile_path) + # remove gems from each gemfiles we have + Bundler.definition.gemfiles.each do |path| + deps = remove_deps(path) + + show_warning("No gems were removed from the gemfile.") if deps.empty? + + deps.each {|dep| Bundler.ui.confirm "#{SharedHelpers.pretty_dependency(dep)} was removed." } + end + + # Invalidate the cached Bundler.definition. + # This prevents e.g. `bundle remove ...` from using outdated information. + Bundler.reset_paths! + end + + private + + def conservative_version(spec) + version = spec.version + return ">= 0" if version.nil? + segments = version.segments + seg_end_index = version >= Gem::Version.new("1.0") ? 1 : 2 + + prerelease_suffix = version.to_s.gsub(version.release.to_s, "") if version.prerelease? + "#{version_prefix}#{segments[0..seg_end_index].join(".")}#{prerelease_suffix}" + end + + def version_prefix + if @options[:strict] + "= " + elsif @options[:optimistic] + ">= " + else + "~> " + end + end + + def build_gem_lines(conservative_versioning) + @deps.map do |d| + name = d.name.dump + + requirement = if conservative_versioning + ", \"#{conservative_version(@definition.specs[d.name][0])}\"" + else + ", #{d.requirement.as_list.map(&:dump).join(", ")}" + end + + if d.groups != Array(:default) + group = d.groups.size == 1 ? ", :group => #{d.groups.first.inspect}" : ", :groups => #{d.groups.inspect}" + end + + source = ", :source => \"#{d.source}\"" unless d.source.nil? + path = ", :path => \"#{d.path}\"" unless d.path.nil? + git = ", :git => \"#{d.git}\"" unless d.git.nil? + github = ", :github => \"#{d.github}\"" unless d.github.nil? + branch = ", :branch => \"#{d.branch}\"" unless d.branch.nil? + ref = ", :ref => \"#{d.ref}\"" unless d.ref.nil? + require_path = ", :require => #{convert_autorequire(d.autorequire)}" unless d.autorequire.nil? + + %(gem #{name}#{requirement}#{group}#{source}#{path}#{git}#{github}#{branch}#{ref}#{require_path}) + end.join("\n") + end + + def append_to(gemfile_path, new_gem_lines) + gemfile_path.open("a") do |f| + f.puts + f.puts new_gem_lines + end + end + + # evaluates a gemfile to remove the specified gem + # from it. + def remove_deps(gemfile_path) + initial_gemfile = File.readlines(gemfile_path) + + Bundler.ui.info "Removing gems from #{gemfile_path}" + + # evaluate the Gemfile we have + builder = Dsl.new + builder.eval_gemfile(gemfile_path) + + removed_deps = remove_gems_from_dependencies(builder, @deps, gemfile_path) + + # abort the operation if no gems were removed + # no need to operate on gemfile further + return [] if removed_deps.empty? + + cleaned_gemfile = remove_gems_from_gemfile(@deps, gemfile_path) + + SharedHelpers.write_to_gemfile(gemfile_path, cleaned_gemfile) + + # check for errors + # including extra gems being removed + # or some gems not being removed + # and return the actual removed deps + cross_check_for_errors(gemfile_path, builder.dependencies, removed_deps, initial_gemfile) + end + + # @param [Dsl] builder Dsl object of current Gemfile. + # @param [Array] gems Array of names of gems to be removed. + # @param [Pathname] gemfile_path Path of the Gemfile. + # @return [Array] Array of removed dependencies. + def remove_gems_from_dependencies(builder, gems, gemfile_path) + removed_deps = [] + + gems.each do |gem_name| + deleted_dep = builder.dependencies.find {|d| d.name == gem_name } + + if deleted_dep.nil? + raise GemfileError, "`#{gem_name}` is not specified in #{gemfile_path} so it could not be removed." + end + + builder.dependencies.delete(deleted_dep) + + removed_deps << deleted_dep + end + + removed_deps + end + + # @param [Array] gems Array of names of gems to be removed. + # @param [Pathname] gemfile_path The Gemfile from which to remove dependencies. + def remove_gems_from_gemfile(gems, gemfile_path) + patterns = /gem\s+(['"])#{Regexp.union(gems)}\1|gem\s*\((['"])#{Regexp.union(gems)}\2\)/ + new_gemfile = [] + multiline_removal = false + File.readlines(gemfile_path).each do |line| + match_data = line.match(patterns) + if match_data && is_not_within_comment?(line, match_data) + multiline_removal = line.rstrip.end_with?(",") + # skip lines which match the regex + next + end + + # skip followup lines until line does not end with ',' + new_gemfile << line unless multiline_removal + multiline_removal = line.rstrip.end_with?(",") if multiline_removal + end + + # remove line \n and append them with other strings + new_gemfile.each_with_index do |_line, index| + if new_gemfile[index + 1] == "\n" + new_gemfile[index] += new_gemfile[index + 1] + new_gemfile.delete_at(index + 1) + end + end + + %w[group source env install_if].each {|block| remove_nested_blocks(new_gemfile, block) } + + new_gemfile.join.chomp + end + + # @param [String] line Individual line of gemfile content. + # @param [MatchData] match_data Data about Regex match. + def is_not_within_comment?(line, match_data) + match_start_index = match_data.offset(0).first + !line[0..match_start_index].include?("#") + end + + # @param [Array] gemfile Array of gemfile contents. + # @param [String] block_name Name of block name to look for. + def remove_nested_blocks(gemfile, block_name) + nested_blocks = 0 + + # count number of nested blocks + gemfile.each_with_index {|line, index| nested_blocks += 1 if !gemfile[index + 1].nil? && gemfile[index + 1].include?(block_name) && line.include?(block_name) } + + while nested_blocks >= 0 + nested_blocks -= 1 + + gemfile.each_with_index do |line, index| + next unless !line.nil? && line.strip.start_with?(block_name) + if gemfile[index + 1] =~ /^\s*end\s*$/ + gemfile[index] = nil + gemfile[index + 1] = nil + end + end + + gemfile.compact! + end + end + + # @param [Pathname] gemfile_path The Gemfile from which to remove dependencies. + # @param [Array] original_deps Array of original dependencies. + # @param [Array] removed_deps Array of removed dependencies. + # @param [Array] initial_gemfile Contents of original Gemfile before any operation. + def cross_check_for_errors(gemfile_path, original_deps, removed_deps, initial_gemfile) + # evaluate the new gemfile to look for any failure cases + builder = Dsl.new + builder.eval_gemfile(gemfile_path) + + # record gems which were removed but not requested + extra_removed_gems = original_deps - builder.dependencies + + # if some extra gems were removed then raise error + # and revert Gemfile to original + unless extra_removed_gems.empty? + SharedHelpers.write_to_gemfile(gemfile_path, initial_gemfile.join) + + raise InvalidOption, "Gems could not be removed. #{extra_removed_gems.join(", ")} would also have been removed. Bundler cannot continue." + end + + # record gems which could not be removed due to some reasons + errored_deps = builder.dependencies.select {|d| d.gemfile == gemfile_path } & removed_deps.select {|d| d.gemfile == gemfile_path } + + show_warning "#{errored_deps.map(&:name).join(", ")} could not be removed." unless errored_deps.empty? + + # return actual removed dependencies + removed_deps - errored_deps + end + + def show_warning(message) + Bundler.ui.info Bundler.ui.add_color(message, :yellow) + end + + def convert_autorequire(autorequire) + autorequire = autorequire.first + return autorequire if autorequire == "false" + autorequire.inspect + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/inline.rb b/games/FNaFB2/Ruby/stdlib/bundler/inline.rb new file mode 100644 index 0000000..25e055f --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/inline.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +# Allows for declaring a Gemfile inline in a ruby script, optionally installing +# any gems that aren't already installed on the user's system. +# +# @note Every gem that is specified in this 'Gemfile' will be `require`d, as if +# the user had manually called `Bundler.require`. To avoid a requested gem +# being automatically required, add the `:require => false` option to the +# `gem` dependency declaration. +# +# @param install [Boolean] whether gems that aren't already installed on the +# user's system should be installed. +# Defaults to `false`. +# +# @param gemfile [Proc] a block that is evaluated as a `Gemfile`. +# +# @example Using an inline Gemfile +# +# #!/usr/bin/env ruby +# +# require 'bundler/inline' +# +# gemfile do +# source 'https://rubygems.org' +# gem 'json', require: false +# gem 'nap', require: 'rest' +# gem 'cocoapods', '~> 0.34.1' +# end +# +# puts Pod::VERSION # => "0.34.4" +# +def gemfile(install = false, options = {}, &gemfile) + require_relative "../bundler" + + opts = options.dup + ui = opts.delete(:ui) { Bundler::UI::Shell.new } + ui.level = "silent" if opts.delete(:quiet) + raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty? + + begin + Bundler.instance_variable_set(:@bundle_path, Pathname.new(Gem.dir)) + old_gemfile = ENV["BUNDLE_GEMFILE"] + Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", "Gemfile" + + Bundler::Plugin.gemfile_install(&gemfile) if Bundler.feature_flag.plugins? + builder = Bundler::Dsl.new + builder.instance_eval(&gemfile) + builder.check_primary_source_safety + + Bundler.settings.temporary(:deployment => false, :frozen => false) do + definition = builder.to_definition(nil, true) + def definition.lock(*); end + definition.validate_runtime! + + Bundler.ui = install ? ui : Bundler::UI::Silent.new + if install || definition.missing_specs? + Bundler.settings.temporary(:inline => true, :no_install => false) do + installer = Bundler::Installer.install(Bundler.root, definition, :system => true) + installer.post_install_messages.each do |name, message| + Bundler.ui.info "Post-install message from #{name}:\n#{message}" + end + end + end + + runtime = Bundler::Runtime.new(nil, definition) + runtime.setup.require + end + ensure + if old_gemfile + ENV["BUNDLE_GEMFILE"] = old_gemfile + else + ENV["BUNDLE_GEMFILE"] = "" + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/installer.rb b/games/FNaFB2/Ruby/stdlib/bundler/installer.rb new file mode 100644 index 0000000..1b17de5 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/installer.rb @@ -0,0 +1,281 @@ +# frozen_string_literal: true + +require_relative "worker" +require_relative "installer/parallel_installer" +require_relative "installer/standalone" +require_relative "installer/gem_installer" + +module Bundler + class Installer + class << self + attr_accessor :ambiguous_gems + + Installer.ambiguous_gems = [] + end + + attr_reader :post_install_messages, :definition + + # Begins the installation process for Bundler. + # For more information see the #run method on this class. + def self.install(root, definition, options = {}) + installer = new(root, definition) + Plugin.hook(Plugin::Events::GEM_BEFORE_INSTALL_ALL, definition.dependencies) + installer.run(options) + Plugin.hook(Plugin::Events::GEM_AFTER_INSTALL_ALL, definition.dependencies) + installer + end + + def initialize(root, definition) + @root = root + @definition = definition + @post_install_messages = {} + end + + # Runs the install procedures for a specific Gemfile. + # + # Firstly, this method will check to see if `Bundler.bundle_path` exists + # and if not then Bundler will create the directory. This is usually the same + # location as RubyGems which typically is the `~/.gem` directory + # unless other specified. + # + # Secondly, it checks if Bundler has been configured to be "frozen". + # Frozen ensures that the Gemfile and the Gemfile.lock file are matching. + # This stops a situation where a developer may update the Gemfile but may not run + # `bundle install`, which leads to the Gemfile.lock file not being correctly updated. + # If this file is not correctly updated then any other developer running + # `bundle install` will potentially not install the correct gems. + # + # Thirdly, Bundler checks if there are any dependencies specified in the Gemfile. + # If there are no dependencies specified then Bundler returns a warning message stating + # so and this method returns. + # + # Fourthly, Bundler checks if the Gemfile.lock exists, and if so + # then proceeds to set up a definition based on the Gemfile and the Gemfile.lock. + # During this step Bundler will also download information about any new gems + # that are not in the Gemfile.lock and resolve any dependencies if needed. + # + # Fifthly, Bundler resolves the dependencies either through a cache of gems or by remote. + # This then leads into the gems being installed, along with stubs for their executables, + # but only if the --binstubs option has been passed or Bundler.options[:bin] has been set + # earlier. + # + # Sixthly, a new Gemfile.lock is created from the installed gems to ensure that the next time + # that a user runs `bundle install` they will receive any updates from this process. + # + # Finally, if the user has specified the standalone flag, Bundler will generate the needed + # require paths and save them in a `setup.rb` file. See `bundle standalone --help` for more + # information. + def run(options) + Bundler.create_bundle_path + + ProcessLock.lock do + if Bundler.frozen_bundle? + @definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment]) + end + + if @definition.dependencies.empty? + Bundler.ui.warn "The Gemfile specifies no dependencies" + lock + return + end + + if resolve_if_needed(options) + ensure_specs_are_compatible! + load_plugins + options.delete(:jobs) + else + options[:jobs] = 1 # to avoid the overhead of Bundler::Worker + end + install(options) + + Gem::Specification.reset # invalidate gem specification cache so that installed gems are immediately available + + lock unless Bundler.frozen_bundle? + Standalone.new(options[:standalone], @definition).generate if options[:standalone] + end + end + + def generate_bundler_executable_stubs(spec, options = {}) + if options[:binstubs_cmd] && spec.executables.empty? + options = {} + spec.runtime_dependencies.each do |dep| + bins = @definition.specs[dep].first.executables + options[dep.name] = bins unless bins.empty? + end + if options.any? + Bundler.ui.warn "#{spec.name} has no executables, but you may want " \ + "one from a gem it depends on." + options.each {|name, bins| Bundler.ui.warn " #{name} has: #{bins.join(", ")}" } + else + Bundler.ui.warn "There are no executables for the gem #{spec.name}." + end + return + end + + # double-assignment to avoid warnings about variables that will be used by ERB + bin_path = Bundler.bin_path + bin_path = bin_path + relative_gemfile_path = Bundler.default_gemfile.relative_path_from(bin_path) + relative_gemfile_path = relative_gemfile_path + ruby_command = Thor::Util.ruby_command + ruby_command = ruby_command + template_path = File.expand_path("templates/Executable", __dir__) + if spec.name == "bundler" + template_path += ".bundler" + spec.executables = %(bundle) + end + template = File.read(template_path) + + exists = [] + spec.executables.each do |executable| + binstub_path = "#{bin_path}/#{executable}" + if File.exist?(binstub_path) && !options[:force] + exists << executable + next + end + + mode = Gem.win_platform? ? "wb:UTF-8" : "w" + require "erb" + content = if RUBY_VERSION >= "2.6" + ERB.new(template, :trim_mode => "-").result(binding) + else + ERB.new(template, nil, "-").result(binding) + end + + File.write(binstub_path, content, :mode => mode, :perm => 0o777 & ~File.umask) + if Gem.win_platform? || options[:all_platforms] + prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n" + File.write("#{binstub_path}.cmd", prefix + content, :mode => mode) + end + end + + if options[:binstubs_cmd] && exists.any? + case exists.size + when 1 + Bundler.ui.warn "Skipped #{exists[0]} since it already exists." + when 2 + Bundler.ui.warn "Skipped #{exists.join(" and ")} since they already exist." + else + items = exists[0...-1].empty? ? nil : exists[0...-1].join(", ") + skipped = [items, exists[-1]].compact.join(" and ") + Bundler.ui.warn "Skipped #{skipped} since they already exist." + end + Bundler.ui.warn "If you want to overwrite skipped stubs, use --force." + end + end + + def generate_standalone_bundler_executable_stubs(spec, options = {}) + # double-assignment to avoid warnings about variables that will be used by ERB + bin_path = Bundler.bin_path + unless path = Bundler.settings[:path] + raise "Can't standalone without an explicit path set" + end + standalone_path = Bundler.root.join(path).relative_path_from(bin_path) + standalone_path = standalone_path + template = File.read(File.expand_path("templates/Executable.standalone", __dir__)) + ruby_command = Thor::Util.ruby_command + ruby_command = ruby_command + + spec.executables.each do |executable| + next if executable == "bundle" + executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path) + executable_path = executable_path + + mode = Gem.win_platform? ? "wb:UTF-8" : "w" + require "erb" + content = if RUBY_VERSION >= "2.6" + ERB.new(template, :trim_mode => "-").result(binding) + else + ERB.new(template, nil, "-").result(binding) + end + + File.write("#{bin_path}/#{executable}", content, :mode => mode, :perm => 0o755) + if Gem.win_platform? || options[:all_platforms] + prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n" + File.write("#{bin_path}/#{executable}.cmd", prefix + content, :mode => mode) + end + end + end + + private + + # the order that the resolver provides is significant, since + # dependencies might affect the installation of a gem. + # that said, it's a rare situation (other than rake), and parallel + # installation is SO MUCH FASTER. so we let people opt in. + def install(options) + force = options["force"] + jobs = installation_parallelization(options) + install_in_parallel jobs, options[:standalone], force + end + + def installation_parallelization(options) + if jobs = options.delete(:jobs) + return jobs + end + + if jobs = Bundler.settings[:jobs] + return jobs + end + + Bundler.settings.processor_count + end + + def load_plugins + Bundler.rubygems.load_plugins + + requested_path_gems = @definition.requested_specs.select {|s| s.source.is_a?(Source::Path) } + path_plugin_files = requested_path_gems.map do |spec| + begin + Bundler.rubygems.spec_matches_for_glob(spec, "rubygems_plugin#{Bundler.rubygems.suffix_pattern}") + rescue TypeError + error_message = "#{spec.name} #{spec.version} has an invalid gemspec" + raise Gem::InvalidSpecificationException, error_message + end + end.flatten + Bundler.rubygems.load_plugin_files(path_plugin_files) + Bundler.rubygems.load_env_plugins + end + + def ensure_specs_are_compatible! + @definition.specs.each do |spec| + unless spec.matches_current_ruby? + raise InstallError, "#{spec.full_name} requires ruby version #{spec.required_ruby_version}, " \ + "which is incompatible with the current version, #{Gem.ruby_version}" + end + unless spec.matches_current_rubygems? + raise InstallError, "#{spec.full_name} requires rubygems version #{spec.required_rubygems_version}, " \ + "which is incompatible with the current version, #{Gem.rubygems_version}" + end + end + end + + def install_in_parallel(size, standalone, force = false) + spec_installations = ParallelInstaller.call(self, @definition.specs, size, standalone, force) + spec_installations.each do |installation| + post_install_messages[installation.name] = installation.post_install_message if installation.has_post_install_message? + end + end + + # returns whether or not a re-resolve was needed + def resolve_if_needed(options) + if !@definition.unlocking? && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file? + return false if @definition.nothing_changed? && !@definition.missing_specs? + end + + if options["local"] + @definition.resolve_with_cache! + elsif options["prefer-local"] + @definition.resolve_prefering_local! + else + @definition.resolve_remotely! + end + + true + end + + def lock(opts = {}) + @definition.lock(Bundler.default_lockfile, opts[:preserve_unknown_sections]) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/installer/gem_installer.rb b/games/FNaFB2/Ruby/stdlib/bundler/installer/gem_installer.rb new file mode 100644 index 0000000..9a013ee --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/installer/gem_installer.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +module Bundler + class GemInstaller + attr_reader :spec, :standalone, :worker, :force, :installer + + def initialize(spec, installer, standalone = false, worker = 0, force = false) + @spec = spec + @installer = installer + @standalone = standalone + @worker = worker + @force = force + end + + def install_from_spec + post_install_message = install + Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}" + generate_executable_stubs + return true, post_install_message + rescue Bundler::InstallHookError, Bundler::SecurityError, Bundler::APIResponseMismatchError + raise + rescue Errno::ENOSPC + return false, out_of_space_message + rescue Bundler::BundlerError, Gem::InstallError, Bundler::APIResponseInvalidDependenciesError => e + return false, specific_failure_message(e) + end + + private + + def specific_failure_message(e) + message = "#{e.class}: #{e.message}\n" + message += " " + e.backtrace.join("\n ") + "\n\n" + message = message.lines.first + Bundler.ui.add_color(message.lines.drop(1).join, :clear) + message + Bundler.ui.add_color(failure_message, :red) + end + + def failure_message + install_error_message + end + + def install_error_message + "An error occurred while installing #{spec.name} (#{spec.version}), and Bundler cannot continue." + end + + def spec_settings + # Fetch the build settings, if there are any + if settings = Bundler.settings["build.#{spec.name}"] + require "shellwords" + Shellwords.shellsplit(settings) + end + end + + def install + spec.source.install( + spec, + :force => force, + :ensure_builtin_gems_cached => standalone, + :build_args => Array(spec_settings), + :previous_spec => previous_spec, + ) + end + + def previous_spec + locked_gems = installer.definition.locked_gems + return unless locked_gems + + locked_gems.specs.find {|s| s.name == spec.name } + end + + def out_of_space_message + "#{install_error_message}\nYour disk is out of space. Free some space to be able to install your bundle." + end + + def generate_executable_stubs + return if Bundler.feature_flag.forget_cli_options? + return if Bundler.settings[:inline] + if Bundler.settings[:bin] && standalone + installer.generate_standalone_bundler_executable_stubs(spec) + elsif Bundler.settings[:bin] + installer.generate_bundler_executable_stubs(spec, :force => true) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/installer/parallel_installer.rb b/games/FNaFB2/Ruby/stdlib/bundler/installer/parallel_installer.rb new file mode 100644 index 0000000..5b6680e --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/installer/parallel_installer.rb @@ -0,0 +1,250 @@ +# frozen_string_literal: true + +require_relative "../worker" +require_relative "gem_installer" + +module Bundler + class ParallelInstaller + class SpecInstallation + attr_accessor :spec, :name, :full_name, :post_install_message, :state, :error + def initialize(spec) + @spec = spec + @name = spec.name + @full_name = spec.full_name + @state = :none + @post_install_message = "" + @error = nil + end + + def installed? + state == :installed + end + + def enqueued? + state == :enqueued + end + + def failed? + state == :failed + end + + def ready_to_enqueue? + state == :none + end + + def has_post_install_message? + !post_install_message.empty? + end + + def ignorable_dependency?(dep) + dep.type == :development || dep.name == @name + end + + # Checks installed dependencies against spec's dependencies to make + # sure needed dependencies have been installed. + def dependencies_installed?(all_specs) + installed_specs = all_specs.select(&:installed?).map(&:name) + dependencies.all? {|d| installed_specs.include? d.name } + end + + # Represents only the non-development dependencies, the ones that are + # itself and are in the total list. + def dependencies + @dependencies ||= all_dependencies.reject {|dep| ignorable_dependency? dep } + end + + def missing_lockfile_dependencies(all_spec_names) + dependencies.reject {|dep| all_spec_names.include? dep.name } + end + + # Represents all dependencies + def all_dependencies + @spec.dependencies + end + + def to_s + "#<#{self.class} #{full_name} (#{state})>" + end + end + + def self.call(*args) + new(*args).call + end + + attr_reader :size + + def initialize(installer, all_specs, size, standalone, force) + @installer = installer + @size = size + @standalone = standalone + @force = force + @specs = all_specs.map {|s| SpecInstallation.new(s) } + @spec_set = all_specs + @rake = @specs.find {|s| s.name == "rake" } + end + + def call + check_for_corrupt_lockfile + + if @rake + do_install(@rake, 0) + Gem::Specification.reset + end + + if @size > 1 + install_with_worker + else + install_serially + end + + check_for_unmet_dependencies + + handle_error if failed_specs.any? + @specs + ensure + worker_pool && worker_pool.stop + end + + def check_for_unmet_dependencies + unmet_dependencies = @specs.map do |s| + [ + s, + s.dependencies.reject {|dep| @specs.any? {|spec| dep.matches_spec?(spec.spec) } }, + ] + end.reject {|a| a.last.empty? } + return if unmet_dependencies.empty? + + warning = [] + warning << "Your lockfile doesn't include a valid resolution." + warning << "You can fix this by regenerating your lockfile or trying to manually editing the bad locked gems to a version that satisfies all dependencies." + warning << "The unmet dependencies are:" + + unmet_dependencies.each do |spec, unmet_spec_dependencies| + unmet_spec_dependencies.each do |unmet_spec_dependency| + warning << "* #{unmet_spec_dependency}, depended upon #{spec.full_name}, unsatisfied by #{@specs.find {|s| s.name == unmet_spec_dependency.name && !unmet_spec_dependency.matches_spec?(s.spec) }.full_name}" + end + end + + Bundler.ui.warn(warning.join("\n")) + end + + def check_for_corrupt_lockfile + missing_dependencies = @specs.map do |s| + [ + s, + s.missing_lockfile_dependencies(@specs.map(&:name)), + ] + end.reject {|a| a.last.empty? } + return if missing_dependencies.empty? + + warning = [] + warning << "Your lockfile was created by an old Bundler that left some things out." + if @size != 1 + warning << "Because of the missing DEPENDENCIES, we can only install gems one at a time, instead of installing #{@size} at a time." + @size = 1 + end + warning << "You can fix this by adding the missing gems to your Gemfile, running bundle install, and then removing the gems from your Gemfile." + warning << "The missing gems are:" + + missing_dependencies.each do |spec, missing| + warning << "* #{missing.map(&:name).join(", ")} depended upon by #{spec.name}" + end + + Bundler.ui.warn(warning.join("\n")) + end + + private + + def failed_specs + @specs.select(&:failed?) + end + + def install_with_worker + enqueue_specs + process_specs until finished_installing? + end + + def install_serially + until finished_installing? + raise "failed to find a spec to enqueue while installing serially" unless spec_install = @specs.find(&:ready_to_enqueue?) + spec_install.state = :enqueued + do_install(spec_install, 0) + end + end + + def worker_pool + @worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda {|spec_install, worker_num| + do_install(spec_install, worker_num) + } + end + + def do_install(spec_install, worker_num) + Plugin.hook(Plugin::Events::GEM_BEFORE_INSTALL, spec_install) + gem_installer = Bundler::GemInstaller.new( + spec_install.spec, @installer, @standalone, worker_num, @force + ) + success, message = gem_installer.install_from_spec + if success + spec_install.state = :installed + spec_install.post_install_message = message unless message.nil? + else + spec_install.error = "#{message}\n\n#{require_tree_for_spec(spec_install.spec)}" + spec_install.state = :failed + end + Plugin.hook(Plugin::Events::GEM_AFTER_INSTALL, spec_install) + spec_install + end + + # Dequeue a spec and save its post-install message and then enqueue the + # remaining specs. + # Some specs might've had to wait til this spec was installed to be + # processed so the call to `enqueue_specs` is important after every + # dequeue. + def process_specs + worker_pool.deq + enqueue_specs + end + + def finished_installing? + @specs.all? do |spec| + return true if spec.failed? + spec.installed? + end + end + + def handle_error + errors = failed_specs.map(&:error) + if exception = errors.find {|e| e.is_a?(Bundler::BundlerError) } + raise exception + end + raise Bundler::InstallError, errors.join("\n\n") + end + + def require_tree_for_spec(spec) + tree = @spec_set.what_required(spec) + t = String.new("In #{File.basename(SharedHelpers.default_gemfile)}:\n") + tree.each_with_index do |s, depth| + t << " " * depth.succ << s.name + unless tree.last == s + t << %( was resolved to #{s.version}, which depends on) + end + t << %(\n) + end + t + end + + # Keys in the remains hash represent uninstalled gems specs. + # We enqueue all gem specs that do not have any dependencies. + # Later we call this lambda again to install specs that depended on + # previously installed specifications. We continue until all specs + # are installed. + def enqueue_specs + @specs.select(&:ready_to_enqueue?).each do |spec| + if spec.dependencies_installed? @specs + spec.state = :enqueued + worker_pool.enq spec + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/installer/standalone.rb b/games/FNaFB2/Ruby/stdlib/bundler/installer/standalone.rb new file mode 100644 index 0000000..2756626 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/installer/standalone.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +module Bundler + class Standalone + def initialize(groups, definition) + @specs = definition.specs_for(groups) + end + + def generate + SharedHelpers.filesystem_access(bundler_path) do |p| + FileUtils.mkdir_p(p) + end + File.open File.join(bundler_path, "setup.rb"), "w" do |file| + file.puts "require 'rbconfig'" + file.puts define_path_helpers + file.puts reverse_rubygems_kernel_mixin + paths.each do |path| + if Pathname.new(path).absolute? + file.puts %($:.unshift "#{path}") + else + file.puts %($:.unshift File.expand_path("\#{__dir__}/#{path}")) + end + end + end + end + + private + + def paths + @specs.map do |spec| + next if spec.name == "bundler" + Array(spec.require_paths).map do |path| + gem_path(path, spec). + sub(version_dir, '#{RUBY_ENGINE}/#{Gem.ruby_api_version}'). + sub(extensions_dir, 'extensions/\k/#{Gem.extension_api_version}') + # This is a static string intentionally. It's interpolated at a later time. + end + end.flatten.compact + end + + def version_dir + "#{RUBY_ENGINE}/#{Gem.ruby_api_version}" + end + + def extensions_dir + %r{extensions/(?[^/]+)/#{Regexp.escape(Gem.extension_api_version)}} + end + + def bundler_path + Bundler.root.join(Bundler.settings[:path].to_s, "bundler") + end + + def gem_path(path, spec) + full_path = Pathname.new(path).absolute? ? path : File.join(spec.full_gem_path, path) + if spec.source.instance_of?(Source::Path) + full_path + else + Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path)).to_s + end + rescue TypeError + error_message = "#{spec.name} #{spec.version} has an invalid gemspec" + raise Gem::InvalidSpecificationException.new(error_message) + end + + def define_path_helpers + <<~'END' + unless defined?(Gem) + module Gem + def self.ruby_api_version + RbConfig::CONFIG["ruby_version"] + end + + def self.extension_api_version + if 'no' == RbConfig::CONFIG['ENABLE_SHARED'] + "#{ruby_api_version}-static" + else + ruby_api_version + end + end + end + end + END + end + + def reverse_rubygems_kernel_mixin + <<~END + kernel = (class << ::Kernel; self; end) + [kernel, ::Kernel].each do |k| + if k.private_method_defined?(:gem_original_require) + private_require = k.private_method_defined?(:require) + k.send(:remove_method, :require) + k.send(:define_method, :require, k.instance_method(:gem_original_require)) + k.send(:private, :require) if private_require + end + end + END + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/lazy_specification.rb b/games/FNaFB2/Ruby/stdlib/bundler/lazy_specification.rb new file mode 100644 index 0000000..949e826 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/lazy_specification.rb @@ -0,0 +1,159 @@ +# frozen_string_literal: true + +module Bundler + class LazySpecification + include MatchPlatform + + attr_reader :name, :version, :dependencies, :platform + attr_accessor :source, :remote, :force_ruby_platform + + def initialize(name, version, platform, source = nil) + @name = name + @version = version + @dependencies = [] + @platform = platform || Gem::Platform::RUBY + @source = source + @specification = nil + end + + def full_name + if platform == Gem::Platform::RUBY + "#{@name}-#{@version}" + else + "#{@name}-#{@version}-#{platform}" + end + end + + def ==(other) + identifier == other.identifier + end + + def eql?(other) + identifier.eql?(other.identifier) + end + + def hash + identifier.hash + end + + ## + # Does this locked specification satisfy +dependency+? + # + # NOTE: Rubygems default requirement is ">= 0", which doesn't match + # prereleases of 0 versions, like "0.0.0.dev" or "0.0.0.SNAPSHOT". However, + # bundler users expect those to work. We need to make sure that Gemfile + # dependencies without explicit requirements (which use ">= 0" under the + # hood by default) are still valid for locked specs using this kind of + # versions. The method implements an ad-hoc fix for that. A better solution + # might be to change default rubygems requirement of dependencies to be ">= + # 0.A" but that's a major refactoring likely to break things. Hopefully we + # can attempt it in the future. + # + + def satisfies?(dependency) + effective_requirement = dependency.requirement == Gem::Requirement.default ? Gem::Requirement.new(">= 0.A") : dependency.requirement + + @name == dependency.name && effective_requirement.satisfied_by?(Gem::Version.new(@version)) + end + + def to_lock + out = String.new + + if platform == Gem::Platform::RUBY + out << " #{name} (#{version})\n" + else + out << " #{name} (#{version}-#{platform})\n" + end + + dependencies.sort_by(&:to_s).uniq.each do |dep| + next if dep.type == :development + out << " #{dep.to_lock}\n" + end + + out + end + + def materialize_for_installation + source.local! + + candidates = if source.is_a?(Source::Path) || !ruby_platform_materializes_to_ruby_platform? + target_platform = ruby_platform_materializes_to_ruby_platform? ? platform : local_platform + + GemHelpers.select_best_platform_match(source.specs.search(Dependency.new(name, version)), target_platform) + else + source.specs.search(self) + end + + return self if candidates.empty? + + __materialize__(candidates) + end + + def __materialize__(candidates) + @specification = begin + search = candidates.reverse.find do |spec| + spec.is_a?(StubSpecification) || + (spec.matches_current_ruby? && + spec.matches_current_rubygems?) + end + if search.nil? && Bundler.frozen_bundle? + search = candidates.last + else + search.dependencies = dependencies if search && search.full_name == full_name && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)) + end + search + end + end + + def respond_to?(*args) + super || @specification ? @specification.respond_to?(*args) : nil + end + + def to_s + @__to_s ||= if platform == Gem::Platform::RUBY + "#{name} (#{version})" + else + "#{name} (#{version}-#{platform})" + end + end + + def identifier + @__identifier ||= [name, version, platform.to_s] + end + + def git_version + return unless source.is_a?(Bundler::Source::Git) + " #{source.revision[0..6]}" + end + + private + + def to_ary + nil + end + + def method_missing(method, *args, &blk) + raise "LazySpecification has not been materialized yet (calling :#{method} #{args.inspect})" unless @specification + + return super unless respond_to?(method) + + @specification.send(method, *args, &blk) + end + + # + # For backwards compatibility with existing lockfiles, if the most specific + # locked platform is not a specific platform like x86_64-linux or + # universal-java-11, then we keep the previous behaviour of resolving the + # best platform variant at materiliazation time. For previous bundler + # versions (before 2.2.0) this was always the case (except when the lockfile + # only included non-ruby platforms), but we're also keeping this behaviour + # on newer bundlers unless users generate the lockfile from scratch or + # explicitly add a more specific platform. + # + def ruby_platform_materializes_to_ruby_platform? + generic_platform = generic_local_platform == Gem::Platform::JAVA ? Gem::Platform::JAVA : Gem::Platform::RUBY + + !Bundler.most_specific_locked_platform?(generic_platform) || force_ruby_platform || Bundler.settings[:force_ruby_platform] + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/lockfile_generator.rb b/games/FNaFB2/Ruby/stdlib/bundler/lockfile_generator.rb new file mode 100644 index 0000000..23413db --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/lockfile_generator.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +module Bundler + class LockfileGenerator + attr_reader :definition + attr_reader :out + + # @private + def initialize(definition) + @definition = definition + @out = String.new + end + + def self.generate(definition) + new(definition).generate! + end + + def generate! + add_sources + add_platforms + add_dependencies + add_locked_ruby_version + add_bundled_with + + out + end + + private + + def add_sources + definition.send(:sources).lock_sources.each_with_index do |source, idx| + out << "\n" unless idx.zero? + + # Add the source header + out << source.to_lock + + # Find all specs for this source + specs = definition.resolve.select {|s| source.can_lock?(s) } + add_specs(specs) + end + end + + def add_specs(specs) + # This needs to be sorted by full name so that + # gems with the same name, but different platform + # are ordered consistently + specs.sort_by(&:full_name).each do |spec| + next if spec.name == "bundler".freeze + out << spec.to_lock + end + end + + def add_platforms + add_section("PLATFORMS", definition.platforms) + end + + def add_dependencies + out << "\nDEPENDENCIES\n" + + handled = [] + definition.dependencies.sort_by(&:to_s).each do |dep| + next if handled.include?(dep.name) + out << dep.to_lock << "\n" + handled << dep.name + end + end + + def add_locked_ruby_version + return unless locked_ruby_version = definition.locked_ruby_version + add_section("RUBY VERSION", locked_ruby_version.to_s) + end + + def add_bundled_with + add_section("BUNDLED WITH", Bundler::VERSION) + end + + def add_section(name, value) + out << "\n#{name}\n" + case value + when Array + value.map(&:to_s).sort.each do |val| + out << " #{val}\n" + end + when Hash + value.to_a.sort_by {|k, _| k.to_s }.each do |key, val| + out << " #{key}: #{val}\n" + end + when String + out << " #{value}\n" + else + raise ArgumentError, "#{value.inspect} can't be serialized in a lockfile" + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/lockfile_parser.rb b/games/FNaFB2/Ruby/stdlib/bundler/lockfile_parser.rb new file mode 100644 index 0000000..64fff47 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/lockfile_parser.rb @@ -0,0 +1,224 @@ +# frozen_string_literal: true + +module Bundler + class LockfileParser + attr_reader :sources, :dependencies, :specs, :platforms, :bundler_version, :ruby_version + + BUNDLED = "BUNDLED WITH".freeze + DEPENDENCIES = "DEPENDENCIES".freeze + PLATFORMS = "PLATFORMS".freeze + RUBY = "RUBY VERSION".freeze + GIT = "GIT".freeze + GEM = "GEM".freeze + PATH = "PATH".freeze + PLUGIN = "PLUGIN SOURCE".freeze + SPECS = " specs:".freeze + OPTIONS = /^ ([a-z]+): (.*)$/i.freeze + SOURCE = [GIT, GEM, PATH, PLUGIN].freeze + + SECTIONS_BY_VERSION_INTRODUCED = { + Gem::Version.create("1.0") => [DEPENDENCIES, PLATFORMS, GIT, GEM, PATH].freeze, + Gem::Version.create("1.10") => [BUNDLED].freeze, + Gem::Version.create("1.12") => [RUBY].freeze, + Gem::Version.create("1.13") => [PLUGIN].freeze, + }.freeze + + KNOWN_SECTIONS = SECTIONS_BY_VERSION_INTRODUCED.values.flatten.freeze + + ENVIRONMENT_VERSION_SECTIONS = [BUNDLED, RUBY].freeze + + def self.sections_in_lockfile(lockfile_contents) + lockfile_contents.scan(/^\w[\w ]*$/).uniq + end + + def self.unknown_sections_in_lockfile(lockfile_contents) + sections_in_lockfile(lockfile_contents) - KNOWN_SECTIONS + end + + def self.sections_to_ignore(base_version = nil) + base_version &&= base_version.release + base_version ||= Gem::Version.create("1.0".dup) + attributes = [] + SECTIONS_BY_VERSION_INTRODUCED.each do |version, introduced| + next if version <= base_version + attributes += introduced + end + attributes + end + + def self.bundled_with + lockfile = Bundler.default_lockfile + return unless lockfile.file? + + lockfile_contents = Bundler.read_file(lockfile) + return unless lockfile_contents.include?(BUNDLED) + + lockfile_contents.split(BUNDLED).last.strip + end + + def initialize(lockfile) + @platforms = [] + @sources = [] + @dependencies = {} + @state = nil + @specs = {} + + if lockfile.match(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/) + raise LockfileError, "Your #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} contains merge conflicts.\n" \ + "Run `git checkout HEAD -- #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` first to get a clean lock." + end + + lockfile.split(/(?:\r?\n)+/).each do |line| + if SOURCE.include?(line) + @state = :source + parse_source(line) + elsif line == DEPENDENCIES + @state = :dependency + elsif line == PLATFORMS + @state = :platform + elsif line == RUBY + @state = :ruby + elsif line == BUNDLED + @state = :bundled_with + elsif line =~ /^[^\s]/ + @state = nil + elsif @state + send("parse_#{@state}", line) + end + end + @specs = @specs.values.sort_by(&:identifier) + rescue ArgumentError => e + Bundler.ui.debug(e) + raise LockfileError, "Your lockfile is unreadable. Run `rm #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` " \ + "and then `bundle install` to generate a new lockfile." + end + + def may_include_redundant_platform_specific_gems? + bundler_version.nil? || bundler_version < Gem::Version.new("1.16.2") + end + + private + + TYPES = { + GIT => Bundler::Source::Git, + GEM => Bundler::Source::Rubygems, + PATH => Bundler::Source::Path, + PLUGIN => Bundler::Plugin, + }.freeze + + def parse_source(line) + case line + when SPECS + case @type + when PATH + @current_source = TYPES[@type].from_lock(@opts) + @sources << @current_source + when GIT + @current_source = TYPES[@type].from_lock(@opts) + @sources << @current_source + when GEM + @opts["remotes"] = Array(@opts.delete("remote")).reverse + @current_source = TYPES[@type].from_lock(@opts) + @sources << @current_source + when PLUGIN + @current_source = Plugin.source_from_lock(@opts) + @sources << @current_source + end + when OPTIONS + value = $2 + value = true if value == "true" + value = false if value == "false" + + key = $1 + + if @opts[key] + @opts[key] = Array(@opts[key]) + @opts[key] << value + else + @opts[key] = value + end + when *SOURCE + @current_source = nil + @opts = {} + @type = line + else + parse_spec(line) + end + end + + space = / / + NAME_VERSION = / + ^(#{space}{2}|#{space}{4}|#{space}{6})(?!#{space}) # Exactly 2, 4, or 6 spaces at the start of the line + (.*?) # Name + (?:#{space}\(([^-]*) # Space, followed by version + (?:-(.*))?\))? # Optional platform + (!)? # Optional pinned marker + $ # Line end + /xo.freeze + + def parse_dependency(line) + return unless line =~ NAME_VERSION + spaces = $1 + return unless spaces.size == 2 + name = $2 + version = $3 + pinned = $5 + + version = version.split(",").map(&:strip) if version + + dep = Bundler::Dependency.new(name, version) + + if pinned && dep.name != "bundler" + spec = @specs.find {|_, v| v.name == dep.name } + dep.source = spec.last.source if spec + + # Path sources need to know what the default name / version + # to use in the case that there are no gemspecs present. A fake + # gemspec is created based on the version set on the dependency + # TODO: Use the version from the spec instead of from the dependency + if version && version.size == 1 && version.first =~ /^\s*= (.+)\s*$/ && dep.source.is_a?(Bundler::Source::Path) + dep.source.name = name + dep.source.version = $1 + end + end + + @dependencies[dep.name] = dep + end + + def parse_spec(line) + return unless line =~ NAME_VERSION + spaces = $1 + name = $2 + version = $3 + platform = $4 + + if spaces.size == 4 + version = Gem::Version.new(version) + platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY + @current_spec = LazySpecification.new(name, version, platform) + @current_spec.source = @current_source + @current_source.add_dependency_names(name) + + @specs[@current_spec.identifier] = @current_spec + elsif spaces.size == 6 + version = version.split(",").map(&:strip) if version + dep = Gem::Dependency.new(name, version) + @current_spec.dependencies << dep + end + end + + def parse_platform(line) + @platforms << Gem::Platform.new($1) if line =~ /^ (.*)$/ + end + + def parse_bundled_with(line) + line = line.strip + return unless Gem::Version.correct?(line) + @bundler_version = Gem::Version.create(line) + end + + def parse_ruby(line) + @ruby_version = line.strip + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-add.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-add.1 new file mode 100644 index 0000000..ba4b76f --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-add.1 @@ -0,0 +1,82 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-ADD" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install +. +.SH "SYNOPSIS" +\fBbundle add\fR \fIGEM_NAME\fR [\-\-group=GROUP] [\-\-version=VERSION] [\-\-source=SOURCE] [\-\-path=PATH] [\-\-git=GIT] [\-\-github=GITHUB] [\-\-branch=BRANCH] [\-\-ref=REF] [\-\-skip\-install] [\-\-strict] [\-\-optimistic] +. +.SH "DESCRIPTION" +Adds the named gem to the Gemfile and run \fBbundle install\fR\. \fBbundle install\fR can be avoided by using the flag \fB\-\-skip\-install\fR\. +. +.P +Example: +. +.P +bundle add rails +. +.P +bundle add rails \-\-version "< 3\.0, > 1\.1" +. +.P +bundle add rails \-\-version "~> 5\.0\.0" \-\-source "https://gems\.example\.com" \-\-group "development" +. +.P +bundle add rails \-\-skip\-install +. +.P +bundle add rails \-\-group "development, test" +. +.SH "OPTIONS" +. +.TP +\fB\-\-version\fR, \fB\-v\fR +Specify version requirements(s) for the added gem\. +. +.TP +\fB\-\-group\fR, \fB\-g\fR +Specify the group(s) for the added gem\. Multiple groups should be separated by commas\. +. +.TP +\fB\-\-source\fR, \fB\-s\fR +Specify the source for the added gem\. +. +.TP +\fB\-\-require\fR, \fB\-r\fR +Adds require path to gem\. Provide false, or a path as a string\. +. +.TP +\fB\-\-path\fR +Specify the file system path for the added gem\. +. +.TP +\fB\-\-git\fR +Specify the git source for the added gem\. +. +.TP +\fB\-\-github\fR +Specify the github source for the added gem\. +. +.TP +\fB\-\-branch\fR +Specify the git branch for the added gem\. +. +.TP +\fB\-\-ref\fR +Specify the git ref for the added gem\. +. +.TP +\fB\-\-skip\-install\fR +Adds the gem to the Gemfile but does not install it\. +. +.TP +\fB\-\-optimistic\fR +Adds optimistic declaration of version\. +. +.TP +\fB\-\-strict\fR +Adds strict declaration of version\. + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-add.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-add.1.ronn new file mode 100644 index 0000000..37c92e5 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-add.1.ronn @@ -0,0 +1,58 @@ +bundle-add(1) -- Add gem to the Gemfile and run bundle install +================================================================ + +## SYNOPSIS + +`bundle add` [--group=GROUP] [--version=VERSION] [--source=SOURCE] [--path=PATH] [--git=GIT] [--github=GITHUB] [--branch=BRANCH] [--ref=REF] [--skip-install] [--strict] [--optimistic] + +## DESCRIPTION +Adds the named gem to the Gemfile and run `bundle install`. `bundle install` can be avoided by using the flag `--skip-install`. + +Example: + +bundle add rails + +bundle add rails --version "< 3.0, > 1.1" + +bundle add rails --version "~> 5.0.0" --source "https://gems.example.com" --group "development" + +bundle add rails --skip-install + +bundle add rails --group "development, test" + +## OPTIONS +* `--version`, `-v`: + Specify version requirements(s) for the added gem. + +* `--group`, `-g`: + Specify the group(s) for the added gem. Multiple groups should be separated by commas. + +* `--source`, `-s`: + Specify the source for the added gem. + +* `--require`, `-r`: + Adds require path to gem. Provide false, or a path as a string. + +* `--path`: + Specify the file system path for the added gem. + +* `--git`: + Specify the git source for the added gem. + +* `--github`: + Specify the github source for the added gem. + +* `--branch`: + Specify the git branch for the added gem. + +* `--ref`: + Specify the git ref for the added gem. + +* `--skip-install`: + Adds the gem to the Gemfile but does not install it. + +* `--optimistic`: + Adds optimistic declaration of version. + +* `--strict`: + Adds strict declaration of version. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-binstubs.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-binstubs.1 new file mode 100644 index 0000000..152aec9 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-binstubs.1 @@ -0,0 +1,42 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-BINSTUBS" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems +. +.SH "SYNOPSIS" +\fBbundle binstubs\fR \fIGEM_NAME\fR [\-\-force] [\-\-path PATH] [\-\-standalone] +. +.SH "DESCRIPTION" +Binstubs are scripts that wrap around executables\. Bundler creates a small Ruby file (a binstub) that loads Bundler, runs the command, and puts it into \fBbin/\fR\. Binstubs are a shortcut\-or alternative\- to always using \fBbundle exec\fR\. This gives you a file that can be run directly, and one that will always run the correct gem version used by the application\. +. +.P +For example, if you run \fBbundle binstubs rspec\-core\fR, Bundler will create the file \fBbin/rspec\fR\. That file will contain enough code to load Bundler, tell it to load the bundled gems, and then run rspec\. +. +.P +This command generates binstubs for executables in \fBGEM_NAME\fR\. Binstubs are put into \fBbin\fR, or the \fB\-\-path\fR directory if one has been set\. Calling binstubs with [GEM [GEM]] will create binstubs for all given gems\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-force\fR +Overwrite existing binstubs if they exist\. +. +.TP +\fB\-\-path\fR +The location to install the specified binstubs to\. This defaults to \fBbin\fR\. +. +.TP +\fB\-\-standalone\fR +Makes binstubs that can work without depending on Rubygems or Bundler at runtime\. +. +.TP +\fB\-\-shebang\fR +Specify a different shebang executable name than the default (default \'ruby\') +. +.TP +\fB\-\-all\fR +Create binstubs for all gems in the bundle\. + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-binstubs.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-binstubs.1.ronn new file mode 100644 index 0000000..a961869 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-binstubs.1.ronn @@ -0,0 +1,41 @@ +bundle-binstubs(1) -- Install the binstubs of the listed gems +============================================================= + +## SYNOPSIS + +`bundle binstubs` [--force] [--path PATH] [--standalone] + +## DESCRIPTION + +Binstubs are scripts that wrap around executables. Bundler creates a +small Ruby file (a binstub) that loads Bundler, runs the command, +and puts it into `bin/`. Binstubs are a shortcut-or alternative- +to always using `bundle exec`. This gives you a file that can be run +directly, and one that will always run the correct gem version +used by the application. + +For example, if you run `bundle binstubs rspec-core`, Bundler will create +the file `bin/rspec`. That file will contain enough code to load Bundler, +tell it to load the bundled gems, and then run rspec. + +This command generates binstubs for executables in `GEM_NAME`. +Binstubs are put into `bin`, or the `--path` directory if one has been set. +Calling binstubs with [GEM [GEM]] will create binstubs for all given gems. + +## OPTIONS + +* `--force`: + Overwrite existing binstubs if they exist. + +* `--path`: + The location to install the specified binstubs to. This defaults to `bin`. + +* `--standalone`: + Makes binstubs that can work without depending on Rubygems or Bundler at + runtime. + +* `--shebang`: + Specify a different shebang executable name than the default (default 'ruby') + +* `--all`: + Create binstubs for all gems in the bundle. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-cache.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-cache.1 new file mode 100644 index 0000000..9eb2e1d --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-cache.1 @@ -0,0 +1,61 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-CACHE" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application +. +.SH "SYNOPSIS" +\fBbundle cache\fR +. +.P +alias: \fBpackage\fR, \fBpack\fR +. +.SH "DESCRIPTION" +Copy all of the \fB\.gem\fR files needed to run the application into the \fBvendor/cache\fR directory\. In the future, when running [bundle install(1)][bundle\-install], use the gems in the cache in preference to the ones on \fBrubygems\.org\fR\. +. +.SH "GIT AND PATH GEMS" +The \fBbundle cache\fR command can also package \fB:git\fR and \fB:path\fR dependencies besides \.gem files\. This needs to be explicitly enabled via the \fB\-\-all\fR option\. Once used, the \fB\-\-all\fR option will be remembered\. +. +.SH "SUPPORT FOR MULTIPLE PLATFORMS" +When using gems that have different packages for different platforms, Bundler supports caching of gems for other platforms where the Gemfile has been resolved (i\.e\. present in the lockfile) in \fBvendor/cache\fR\. This needs to be enabled via the \fB\-\-all\-platforms\fR option\. This setting will be remembered in your local bundler configuration\. +. +.SH "REMOTE FETCHING" +By default, if you run \fBbundle install(1)\fR](bundle\-install\.1\.html) after running bundle cache(1) \fIbundle\-cache\.1\.html\fR, bundler will still connect to \fBrubygems\.org\fR to check whether a platform\-specific gem exists for any of the gems in \fBvendor/cache\fR\. +. +.P +For instance, consider this Gemfile(5): +. +.IP "" 4 +. +.nf + +source "https://rubygems\.org" + +gem "nokogiri" +. +.fi +. +.IP "" 0 +. +.P +If you run \fBbundle cache\fR under C Ruby, bundler will retrieve the version of \fBnokogiri\fR for the \fB"ruby"\fR platform\. If you deploy to JRuby and run \fBbundle install\fR, bundler is forced to check to see whether a \fB"java"\fR platformed \fBnokogiri\fR exists\. +. +.P +Even though the \fBnokogiri\fR gem for the Ruby platform is \fItechnically\fR acceptable on JRuby, it has a C extension that does not run on JRuby\. As a result, bundler will, by default, still connect to \fBrubygems\.org\fR to check whether it has a version of one of your gems more specific to your platform\. +. +.P +This problem is also not limited to the \fB"java"\fR platform\. A similar (common) problem can happen when developing on Windows and deploying to Linux, or even when developing on OSX and deploying to Linux\. +. +.P +If you know for sure that the gems packaged in \fBvendor/cache\fR are appropriate for the platform you are on, you can run \fBbundle install \-\-local\fR to skip checking for more appropriate gems, and use the ones in \fBvendor/cache\fR\. +. +.P +One way to be sure that you have the right platformed versions of all your gems is to run \fBbundle cache\fR on an identical machine and check in the gems\. For instance, you can run \fBbundle cache\fR on an identical staging box during your staging process, and check in the \fBvendor/cache\fR before deploying to production\. +. +.P +By default, bundle cache(1) \fIbundle\-cache\.1\.html\fR fetches and also installs the gems to the default location\. To package the dependencies to \fBvendor/cache\fR without installing them to the local install location, you can run \fBbundle cache \-\-no\-install\fR\. +. +.SH "HISTORY" +In Bundler 2\.1, \fBcache\fR took in the functionalities of \fBpackage\fR and now \fBpackage\fR and \fBpack\fR are aliases of \fBcache\fR\. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-cache.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-cache.1.ronn new file mode 100644 index 0000000..46906d2 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-cache.1.ronn @@ -0,0 +1,79 @@ +bundle-cache(1) -- Package your needed `.gem` files into your application +=========================================================================== + +## SYNOPSIS + +`bundle cache` + +alias: `package`, `pack` + +## DESCRIPTION + +Copy all of the `.gem` files needed to run the application into the +`vendor/cache` directory. In the future, when running [bundle install(1)][bundle-install], +use the gems in the cache in preference to the ones on `rubygems.org`. + +## GIT AND PATH GEMS + +The `bundle cache` command can also package `:git` and `:path` dependencies +besides .gem files. This needs to be explicitly enabled via the `--all` option. +Once used, the `--all` option will be remembered. + +## SUPPORT FOR MULTIPLE PLATFORMS + +When using gems that have different packages for different platforms, Bundler +supports caching of gems for other platforms where the Gemfile has been resolved +(i.e. present in the lockfile) in `vendor/cache`. This needs to be enabled via +the `--all-platforms` option. This setting will be remembered in your local +bundler configuration. + +## REMOTE FETCHING + +By default, if you run `bundle install(1)`](bundle-install.1.html) after running +[bundle cache(1)](bundle-cache.1.html), bundler will still connect to `rubygems.org` +to check whether a platform-specific gem exists for any of the gems +in `vendor/cache`. + +For instance, consider this Gemfile(5): + + source "https://rubygems.org" + + gem "nokogiri" + +If you run `bundle cache` under C Ruby, bundler will retrieve +the version of `nokogiri` for the `"ruby"` platform. If you deploy +to JRuby and run `bundle install`, bundler is forced to check to +see whether a `"java"` platformed `nokogiri` exists. + +Even though the `nokogiri` gem for the Ruby platform is +_technically_ acceptable on JRuby, it has a C extension +that does not run on JRuby. As a result, bundler will, by default, +still connect to `rubygems.org` to check whether it has a version +of one of your gems more specific to your platform. + +This problem is also not limited to the `"java"` platform. +A similar (common) problem can happen when developing on Windows +and deploying to Linux, or even when developing on OSX and +deploying to Linux. + +If you know for sure that the gems packaged in `vendor/cache` +are appropriate for the platform you are on, you can run +`bundle install --local` to skip checking for more appropriate +gems, and use the ones in `vendor/cache`. + +One way to be sure that you have the right platformed versions +of all your gems is to run `bundle cache` on an identical +machine and check in the gems. For instance, you can run +`bundle cache` on an identical staging box during your +staging process, and check in the `vendor/cache` before +deploying to production. + +By default, [bundle cache(1)](bundle-cache.1.html) fetches and also +installs the gems to the default location. To package the +dependencies to `vendor/cache` without installing them to the +local install location, you can run `bundle cache --no-install`. + +## HISTORY + +In Bundler 2.1, `cache` took in the functionalities of `package` and now +`package` and `pack` are aliases of `cache`. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-check.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-check.1 new file mode 100644 index 0000000..f6aa698 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-check.1 @@ -0,0 +1,31 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-CHECK" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems +. +.SH "SYNOPSIS" +\fBbundle check\fR [\-\-dry\-run] [\-\-gemfile=FILE] [\-\-path=PATH] +. +.SH "DESCRIPTION" +\fBcheck\fR searches the local machine for each of the gems requested in the Gemfile\. If all gems are found, Bundler prints a success message and exits with a status of 0\. +. +.P +If not, the first missing gem is listed and Bundler exits status 1\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-dry\-run\fR +Locks the [\fBGemfile(5)\fR][Gemfile(5)] before running the command\. +. +.TP +\fB\-\-gemfile\fR +Use the specified gemfile instead of the [\fBGemfile(5)\fR][Gemfile(5)]\. +. +.TP +\fB\-\-path\fR +Specify a different path than the system default (\fB$BUNDLE_PATH\fR or \fB$GEM_HOME\fR)\. Bundler will remember this value for future installs on this machine\. + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-check.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-check.1.ronn new file mode 100644 index 0000000..f2846b8 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-check.1.ronn @@ -0,0 +1,26 @@ +bundle-check(1) -- Verifies if dependencies are satisfied by installed gems +=========================================================================== + +## SYNOPSIS + +`bundle check` [--dry-run] + [--gemfile=FILE] + [--path=PATH] + +## DESCRIPTION + +`check` searches the local machine for each of the gems requested in the +Gemfile. If all gems are found, Bundler prints a success message and exits with +a status of 0. + +If not, the first missing gem is listed and Bundler exits status 1. + +## OPTIONS + +* `--dry-run`: + Locks the [`Gemfile(5)`][Gemfile(5)] before running the command. +* `--gemfile`: + Use the specified gemfile instead of the [`Gemfile(5)`][Gemfile(5)]. +* `--path`: + Specify a different path than the system default (`$BUNDLE_PATH` or `$GEM_HOME`). + Bundler will remember this value for future installs on this machine. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-clean.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-clean.1 new file mode 100644 index 0000000..27e249c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-clean.1 @@ -0,0 +1,24 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-CLEAN" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory +. +.SH "SYNOPSIS" +\fBbundle clean\fR [\-\-dry\-run] [\-\-force] +. +.SH "DESCRIPTION" +This command will remove all unused gems in your bundler directory\. This is useful when you have made many changes to your gem dependencies\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-dry\-run\fR +Print the changes, but do not clean the unused gems\. +. +.TP +\fB\-\-force\fR +Forces cleaning up unused gems even if Bundler is configured to use globally installed gems\. As a consequence, removes all system gems except for the ones in the current application\. + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-clean.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-clean.1.ronn new file mode 100644 index 0000000..dae27c2 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-clean.1.ronn @@ -0,0 +1,18 @@ +bundle-clean(1) -- Cleans up unused gems in your bundler directory +================================================================== + +## SYNOPSIS + +`bundle clean` [--dry-run] [--force] + +## DESCRIPTION + +This command will remove all unused gems in your bundler directory. This is +useful when you have made many changes to your gem dependencies. + +## OPTIONS + +* `--dry-run`: + Print the changes, but do not clean the unused gems. +* `--force`: + Forces cleaning up unused gems even if Bundler is configured to use globally installed gems. As a consequence, removes all system gems except for the ones in the current application. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-config.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-config.1 new file mode 100644 index 0000000..08e08ec --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-config.1 @@ -0,0 +1,515 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-CONFIG" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-config\fR \- Set bundler configuration options +. +.SH "SYNOPSIS" +\fBbundle config\fR list +. +.br +\fBbundle config\fR [get] NAME +. +.br +\fBbundle config\fR [set] NAME VALUE +. +.br +\fBbundle config\fR unset NAME +. +.SH "DESCRIPTION" +This command allows you to interact with Bundler\'s configuration system\. +. +.P +Bundler loads configuration settings in this order: +. +.IP "1." 4 +Local config (\fB/\.bundle/config\fR or \fB$BUNDLE_APP_CONFIG/config\fR) +. +.IP "2." 4 +Environmental variables (\fBENV\fR) +. +.IP "3." 4 +Global config (\fB~/\.bundle/config\fR) +. +.IP "4." 4 +Bundler default config +. +.IP "" 0 +. +.P +Executing \fBbundle config list\fR with will print a list of all bundler configuration for the current bundle, and where that configuration was set\. +. +.P +Executing \fBbundle config get \fR will print the value of that configuration setting, and where it was set\. +. +.P +Executing \fBbundle config set \fR defaults to setting \fBlocal\fR configuration if executing from within a local application, otherwise it will set \fBglobal\fR configuration\. See \fB\-\-local\fR and \fB\-\-global\fR options below\. +. +.P +Executing \fBbundle config set \-\-local \fR will set that configuration in the directory for the local application\. The configuration will be stored in \fB/\.bundle/config\fR\. If \fBBUNDLE_APP_CONFIG\fR is set, the configuration will be stored in \fB$BUNDLE_APP_CONFIG/config\fR\. +. +.P +Executing \fBbundle config set \-\-global \fR will set that configuration to the value specified for all bundles executed as the current user\. The configuration will be stored in \fB~/\.bundle/config\fR\. If \fIname\fR already is set, \fIname\fR will be overridden and user will be warned\. +. +.P +Executing \fBbundle config unset \fR will delete the configuration in both local and global sources\. +. +.P +Executing \fBbundle config unset \-\-global \fR will delete the configuration only from the user configuration\. +. +.P +Executing \fBbundle config unset \-\-local \fR will delete the configuration only from the local application\. +. +.P +Executing bundle with the \fBBUNDLE_IGNORE_CONFIG\fR environment variable set will cause it to ignore all configuration\. +. +.SH "REMEMBERING OPTIONS" +Flags passed to \fBbundle install\fR or the Bundler runtime, such as \fB\-\-path foo\fR or \fB\-\-without production\fR, are remembered between commands and saved to your local application\'s configuration (normally, \fB\./\.bundle/config\fR)\. +. +.P +However, this will be changed in bundler 3, so it\'s better not to rely on this behavior\. If these options must be remembered, it\'s better to set them using \fBbundle config\fR (e\.g\., \fBbundle config set \-\-local path foo\fR)\. +. +.P +The options that can be configured are: +. +.TP +\fBbin\fR +Creates a directory (defaults to \fB~/bin\fR) and place any executables from the gem there\. These executables run in Bundler\'s context\. If used, you might add this directory to your environment\'s \fBPATH\fR variable\. For instance, if the \fBrails\fR gem comes with a \fBrails\fR executable, this flag will create a \fBbin/rails\fR executable that ensures that all referred dependencies will be resolved using the bundled gems\. +. +.TP +\fBdeployment\fR +In deployment mode, Bundler will \'roll\-out\' the bundle for \fBproduction\fR use\. Please check carefully if you want to have this option enabled in \fBdevelopment\fR or \fBtest\fR environments\. +. +.TP +\fBonly\fR +A space\-separated list of groups to install only gems of the specified groups\. +. +.TP +\fBpath\fR +The location to install the specified gems to\. This defaults to Rubygems\' setting\. Bundler shares this location with Rubygems, \fBgem install \.\.\.\fR will have gem installed there, too\. Therefore, gems installed without a \fB\-\-path \.\.\.\fR setting will show up by calling \fBgem list\fR\. Accordingly, gems installed to other locations will not get listed\. +. +.TP +\fBwithout\fR +A space\-separated list of groups referencing gems to skip during installation\. +. +.TP +\fBwith\fR +A space\-separated list of \fBoptional\fR groups referencing gems to include during installation\. +. +.SH "BUILD OPTIONS" +You can use \fBbundle config\fR to give Bundler the flags to pass to the gem installer every time bundler tries to install a particular gem\. +. +.P +A very common example, the \fBmysql\fR gem, requires Snow Leopard users to pass configuration flags to \fBgem install\fR to specify where to find the \fBmysql_config\fR executable\. +. +.IP "" 4 +. +.nf + +gem install mysql \-\- \-\-with\-mysql\-config=/usr/local/mysql/bin/mysql_config +. +.fi +. +.IP "" 0 +. +.P +Since the specific location of that executable can change from machine to machine, you can specify these flags on a per\-machine basis\. +. +.IP "" 4 +. +.nf + +bundle config set \-\-global build\.mysql \-\-with\-mysql\-config=/usr/local/mysql/bin/mysql_config +. +.fi +. +.IP "" 0 +. +.P +After running this command, every time bundler needs to install the \fBmysql\fR gem, it will pass along the flags you specified\. +. +.SH "CONFIGURATION KEYS" +Configuration keys in bundler have two forms: the canonical form and the environment variable form\. +. +.P +For instance, passing the \fB\-\-without\fR flag to bundle install(1) \fIbundle\-install\.1\.html\fR prevents Bundler from installing certain groups specified in the Gemfile(5)\. Bundler persists this value in \fBapp/\.bundle/config\fR so that calls to \fBBundler\.setup\fR do not try to find gems from the \fBGemfile\fR that you didn\'t install\. Additionally, subsequent calls to bundle install(1) \fIbundle\-install\.1\.html\fR remember this setting and skip those groups\. +. +.P +The canonical form of this configuration is \fB"without"\fR\. To convert the canonical form to the environment variable form, capitalize it, and prepend \fBBUNDLE_\fR\. The environment variable form of \fB"without"\fR is \fBBUNDLE_WITHOUT\fR\. +. +.P +Any periods in the configuration keys must be replaced with two underscores when setting it via environment variables\. The configuration key \fBlocal\.rack\fR becomes the environment variable \fBBUNDLE_LOCAL__RACK\fR\. +. +.SH "LIST OF AVAILABLE KEYS" +The following is a list of all configuration keys and their purpose\. You can learn more about their operation in bundle install(1) \fIbundle\-install\.1\.html\fR\. +. +.IP "\(bu" 4 +\fBallow_deployment_source_credential_changes\fR (\fBBUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES\fR): When in deployment mode, allow changing the credentials to a gem\'s source\. Ex: \fBhttps://some\.host\.com/gems/path/\fR \-> \fBhttps://user_name:password@some\.host\.com/gems/path\fR +. +.IP "\(bu" 4 +\fBallow_offline_install\fR (\fBBUNDLE_ALLOW_OFFLINE_INSTALL\fR): Allow Bundler to use cached data when installing without network access\. +. +.IP "\(bu" 4 +\fBauto_clean_without_path\fR (\fBBUNDLE_AUTO_CLEAN_WITHOUT_PATH\fR): Automatically run \fBbundle clean\fR after installing when an explicit \fBpath\fR has not been set and Bundler is not installing into the system gems\. +. +.IP "\(bu" 4 +\fBauto_install\fR (\fBBUNDLE_AUTO_INSTALL\fR): Automatically run \fBbundle install\fR when gems are missing\. +. +.IP "\(bu" 4 +\fBbin\fR (\fBBUNDLE_BIN\fR): Install executables from gems in the bundle to the specified directory\. Defaults to \fBfalse\fR\. +. +.IP "\(bu" 4 +\fBcache_all\fR (\fBBUNDLE_CACHE_ALL\fR): Cache all gems, including path and git gems\. This needs to be explicitly configured on bundler 1 and bundler 2, but will be the default on bundler 3\. +. +.IP "\(bu" 4 +\fBcache_all_platforms\fR (\fBBUNDLE_CACHE_ALL_PLATFORMS\fR): Cache gems for all platforms\. +. +.IP "\(bu" 4 +\fBcache_path\fR (\fBBUNDLE_CACHE_PATH\fR): The directory that bundler will place cached gems in when running \fBbundle package\fR, and that bundler will look in when installing gems\. Defaults to \fBvendor/cache\fR\. +. +.IP "\(bu" 4 +\fBclean\fR (\fBBUNDLE_CLEAN\fR): Whether Bundler should run \fBbundle clean\fR automatically after \fBbundle install\fR\. +. +.IP "\(bu" 4 +\fBconsole\fR (\fBBUNDLE_CONSOLE\fR): The console that \fBbundle console\fR starts\. Defaults to \fBirb\fR\. +. +.IP "\(bu" 4 +\fBdefault_install_uses_path\fR (\fBBUNDLE_DEFAULT_INSTALL_USES_PATH\fR): Whether a \fBbundle install\fR without an explicit \fB\-\-path\fR argument defaults to installing gems in \fB\.bundle\fR\. +. +.IP "\(bu" 4 +\fBdeployment\fR (\fBBUNDLE_DEPLOYMENT\fR): Disallow changes to the \fBGemfile\fR\. When the \fBGemfile\fR is changed and the lockfile has not been updated, running Bundler commands will be blocked\. +. +.IP "\(bu" 4 +\fBdisable_checksum_validation\fR (\fBBUNDLE_DISABLE_CHECKSUM_VALIDATION\fR): Allow installing gems even if they do not match the checksum provided by RubyGems\. +. +.IP "\(bu" 4 +\fBdisable_exec_load\fR (\fBBUNDLE_DISABLE_EXEC_LOAD\fR): Stop Bundler from using \fBload\fR to launch an executable in\-process in \fBbundle exec\fR\. +. +.IP "\(bu" 4 +\fBdisable_local_branch_check\fR (\fBBUNDLE_DISABLE_LOCAL_BRANCH_CHECK\fR): Allow Bundler to use a local git override without a branch specified in the Gemfile\. +. +.IP "\(bu" 4 +\fBdisable_local_revision_check\fR (\fBBUNDLE_DISABLE_LOCAL_REVISION_CHECK\fR): Allow Bundler to use a local git override without checking if the revision present in the lockfile is present in the repository\. +. +.IP "\(bu" 4 +\fBdisable_shared_gems\fR (\fBBUNDLE_DISABLE_SHARED_GEMS\fR): Stop Bundler from accessing gems installed to RubyGems\' normal location\. +. +.IP "\(bu" 4 +\fBdisable_version_check\fR (\fBBUNDLE_DISABLE_VERSION_CHECK\fR): Stop Bundler from checking if a newer Bundler version is available on rubygems\.org\. +. +.IP "\(bu" 4 +\fBforce_ruby_platform\fR (\fBBUNDLE_FORCE_RUBY_PLATFORM\fR): Ignore the current machine\'s platform and install only \fBruby\fR platform gems\. As a result, gems with native extensions will be compiled from source\. +. +.IP "\(bu" 4 +\fBfrozen\fR (\fBBUNDLE_FROZEN\fR): Disallow changes to the \fBGemfile\fR\. When the \fBGemfile\fR is changed and the lockfile has not been updated, running Bundler commands will be blocked\. Defaults to \fBtrue\fR when \fB\-\-deployment\fR is used\. +. +.IP "\(bu" 4 +\fBgem\.github_username\fR (\fBBUNDLE_GEM__GITHUB_USERNAME\fR): Sets a GitHub username or organization to be used in \fBREADME\fR file when you create a new gem via \fBbundle gem\fR command\. It can be overridden by passing an explicit \fB\-\-github\-username\fR flag to \fBbundle gem\fR\. +. +.IP "\(bu" 4 +\fBgem\.push_key\fR (\fBBUNDLE_GEM__PUSH_KEY\fR): Sets the \fB\-\-key\fR parameter for \fBgem push\fR when using the \fBrake release\fR command with a private gemstash server\. +. +.IP "\(bu" 4 +\fBgemfile\fR (\fBBUNDLE_GEMFILE\fR): The name of the file that bundler should use as the \fBGemfile\fR\. This location of this file also sets the root of the project, which is used to resolve relative paths in the \fBGemfile\fR, among other things\. By default, bundler will search up from the current working directory until it finds a \fBGemfile\fR\. +. +.IP "\(bu" 4 +\fBglobal_gem_cache\fR (\fBBUNDLE_GLOBAL_GEM_CACHE\fR): Whether Bundler should cache all gems globally, rather than locally to the installing Ruby installation\. +. +.IP "\(bu" 4 +\fBignore_funding_requests\fR (\fBBUNDLE_IGNORE_FUNDING_REQUESTS\fR): When set, no funding requests will be printed\. +. +.IP "\(bu" 4 +\fBignore_messages\fR (\fBBUNDLE_IGNORE_MESSAGES\fR): When set, no post install messages will be printed\. To silence a single gem, use dot notation like \fBignore_messages\.httparty true\fR\. +. +.IP "\(bu" 4 +\fBinit_gems_rb\fR (\fBBUNDLE_INIT_GEMS_RB\fR): Generate a \fBgems\.rb\fR instead of a \fBGemfile\fR when running \fBbundle init\fR\. +. +.IP "\(bu" 4 +\fBjobs\fR (\fBBUNDLE_JOBS\fR): The number of gems Bundler can install in parallel\. Defaults to the number of available processors\. +. +.IP "\(bu" 4 +\fBno_install\fR (\fBBUNDLE_NO_INSTALL\fR): Whether \fBbundle package\fR should skip installing gems\. +. +.IP "\(bu" 4 +\fBno_prune\fR (\fBBUNDLE_NO_PRUNE\fR): Whether Bundler should leave outdated gems unpruned when caching\. +. +.IP "\(bu" 4 +\fBonly\fR (\fBBUNDLE_ONLY\fR): A space\-separated list of groups to install only gems of the specified groups\. +. +.IP "\(bu" 4 +\fBpath\fR (\fBBUNDLE_PATH\fR): The location on disk where all gems in your bundle will be located regardless of \fB$GEM_HOME\fR or \fB$GEM_PATH\fR values\. Bundle gems not found in this location will be installed by \fBbundle install\fR\. Defaults to \fBGem\.dir\fR\. When \-\-deployment is used, defaults to vendor/bundle\. +. +.IP "\(bu" 4 +\fBpath\.system\fR (\fBBUNDLE_PATH__SYSTEM\fR): Whether Bundler will install gems into the default system path (\fBGem\.dir\fR)\. +. +.IP "\(bu" 4 +\fBpath_relative_to_cwd\fR (\fBBUNDLE_PATH_RELATIVE_TO_CWD\fR) Makes \fB\-\-path\fR relative to the CWD instead of the \fBGemfile\fR\. +. +.IP "\(bu" 4 +\fBplugins\fR (\fBBUNDLE_PLUGINS\fR): Enable Bundler\'s experimental plugin system\. +. +.IP "\(bu" 4 +\fBprefer_patch\fR (BUNDLE_PREFER_PATCH): Prefer updating only to next patch version during updates\. Makes \fBbundle update\fR calls equivalent to \fBbundler update \-\-patch\fR\. +. +.IP "\(bu" 4 +\fBprint_only_version_number\fR (\fBBUNDLE_PRINT_ONLY_VERSION_NUMBER\fR): Print only version number from \fBbundler \-\-version\fR\. +. +.IP "\(bu" 4 +\fBredirect\fR (\fBBUNDLE_REDIRECT\fR): The number of redirects allowed for network requests\. Defaults to \fB5\fR\. +. +.IP "\(bu" 4 +\fBretry\fR (\fBBUNDLE_RETRY\fR): The number of times to retry failed network requests\. Defaults to \fB3\fR\. +. +.IP "\(bu" 4 +\fBsetup_makes_kernel_gem_public\fR (\fBBUNDLE_SETUP_MAKES_KERNEL_GEM_PUBLIC\fR): Have \fBBundler\.setup\fR make the \fBKernel#gem\fR method public, even though RubyGems declares it as private\. +. +.IP "\(bu" 4 +\fBshebang\fR (\fBBUNDLE_SHEBANG\fR): The program name that should be invoked for generated binstubs\. Defaults to the ruby install name used to generate the binstub\. +. +.IP "\(bu" 4 +\fBsilence_deprecations\fR (\fBBUNDLE_SILENCE_DEPRECATIONS\fR): Whether Bundler should silence deprecation warnings for behavior that will be changed in the next major version\. +. +.IP "\(bu" 4 +\fBsilence_root_warning\fR (\fBBUNDLE_SILENCE_ROOT_WARNING\fR): Silence the warning Bundler prints when installing gems as root\. +. +.IP "\(bu" 4 +\fBssl_ca_cert\fR (\fBBUNDLE_SSL_CA_CERT\fR): Path to a designated CA certificate file or folder containing multiple certificates for trusted CAs in PEM format\. +. +.IP "\(bu" 4 +\fBssl_client_cert\fR (\fBBUNDLE_SSL_CLIENT_CERT\fR): Path to a designated file containing a X\.509 client certificate and key in PEM format\. +. +.IP "\(bu" 4 +\fBssl_verify_mode\fR (\fBBUNDLE_SSL_VERIFY_MODE\fR): The SSL verification mode Bundler uses when making HTTPS requests\. Defaults to verify peer\. +. +.IP "\(bu" 4 +\fBsuppress_install_using_messages\fR (\fBBUNDLE_SUPPRESS_INSTALL_USING_MESSAGES\fR): Avoid printing \fBUsing \.\.\.\fR messages during installation when the version of a gem has not changed\. +. +.IP "\(bu" 4 +\fBsystem_bindir\fR (\fBBUNDLE_SYSTEM_BINDIR\fR): The location where RubyGems installs binstubs\. Defaults to \fBGem\.bindir\fR\. +. +.IP "\(bu" 4 +\fBtimeout\fR (\fBBUNDLE_TIMEOUT\fR): The seconds allowed before timing out for network requests\. Defaults to \fB10\fR\. +. +.IP "\(bu" 4 +\fBupdate_requires_all_flag\fR (\fBBUNDLE_UPDATE_REQUIRES_ALL_FLAG\fR): Require passing \fB\-\-all\fR to \fBbundle update\fR when everything should be updated, and disallow passing no options to \fBbundle update\fR\. +. +.IP "\(bu" 4 +\fBuser_agent\fR (\fBBUNDLE_USER_AGENT\fR): The custom user agent fragment Bundler includes in API requests\. +. +.IP "\(bu" 4 +\fBwith\fR (\fBBUNDLE_WITH\fR): A \fB:\fR\-separated list of groups whose gems bundler should install\. +. +.IP "\(bu" 4 +\fBwithout\fR (\fBBUNDLE_WITHOUT\fR): A \fB:\fR\-separated list of groups whose gems bundler should not install\. +. +.IP "" 0 +. +.P +In general, you should set these settings per\-application by using the applicable flag to the bundle install(1) \fIbundle\-install\.1\.html\fR or bundle cache(1) \fIbundle\-cache\.1\.html\fR command\. +. +.P +You can set them globally either via environment variables or \fBbundle config\fR, whichever is preferable for your setup\. If you use both, environment variables will take preference over global settings\. +. +.SH "LOCAL GIT REPOS" +Bundler also allows you to work against a git repository locally instead of using the remote version\. This can be achieved by setting up a local override: +. +.IP "" 4 +. +.nf + +bundle config set \-\-local local\.GEM_NAME /path/to/local/git/repository +. +.fi +. +.IP "" 0 +. +.P +For example, in order to use a local Rack repository, a developer could call: +. +.IP "" 4 +. +.nf + +bundle config set \-\-local local\.rack ~/Work/git/rack +. +.fi +. +.IP "" 0 +. +.P +Now instead of checking out the remote git repository, the local override will be used\. Similar to a path source, every time the local git repository change, changes will be automatically picked up by Bundler\. This means a commit in the local git repo will update the revision in the \fBGemfile\.lock\fR to the local git repo revision\. This requires the same attention as git submodules\. Before pushing to the remote, you need to ensure the local override was pushed, otherwise you may point to a commit that only exists in your local machine\. You\'ll also need to CGI escape your usernames and passwords as well\. +. +.P +Bundler does many checks to ensure a developer won\'t work with invalid references\. Particularly, we force a developer to specify a branch in the \fBGemfile\fR in order to use this feature\. If the branch specified in the \fBGemfile\fR and the current branch in the local git repository do not match, Bundler will abort\. This ensures that a developer is always working against the correct branches, and prevents accidental locking to a different branch\. +. +.P +Finally, Bundler also ensures that the current revision in the \fBGemfile\.lock\fR exists in the local git repository\. By doing this, Bundler forces you to fetch the latest changes in the remotes\. +. +.SH "MIRRORS OF GEM SOURCES" +Bundler supports overriding gem sources with mirrors\. This allows you to configure rubygems\.org as the gem source in your Gemfile while still using your mirror to fetch gems\. +. +.IP "" 4 +. +.nf + +bundle config set \-\-global mirror\.SOURCE_URL MIRROR_URL +. +.fi +. +.IP "" 0 +. +.P +For example, to use a mirror of https://rubygems\.org hosted at https://example\.org: +. +.IP "" 4 +. +.nf + +bundle config set \-\-global mirror\.https://rubygems\.org https://example\.org +. +.fi +. +.IP "" 0 +. +.P +Each mirror also provides a fallback timeout setting\. If the mirror does not respond within the fallback timeout, Bundler will try to use the original server instead of the mirror\. +. +.IP "" 4 +. +.nf + +bundle config set \-\-global mirror\.SOURCE_URL\.fallback_timeout TIMEOUT +. +.fi +. +.IP "" 0 +. +.P +For example, to fall back to rubygems\.org after 3 seconds: +. +.IP "" 4 +. +.nf + +bundle config set \-\-global mirror\.https://rubygems\.org\.fallback_timeout 3 +. +.fi +. +.IP "" 0 +. +.P +The default fallback timeout is 0\.1 seconds, but the setting can currently only accept whole seconds (for example, 1, 15, or 30)\. +. +.SH "CREDENTIALS FOR GEM SOURCES" +Bundler allows you to configure credentials for any gem source, which allows you to avoid putting secrets into your Gemfile\. +. +.IP "" 4 +. +.nf + +bundle config set \-\-global SOURCE_HOSTNAME USERNAME:PASSWORD +. +.fi +. +.IP "" 0 +. +.P +For example, to save the credentials of user \fBclaudette\fR for the gem source at \fBgems\.longerous\.com\fR, you would run: +. +.IP "" 4 +. +.nf + +bundle config set \-\-global gems\.longerous\.com claudette:s00pers3krit +. +.fi +. +.IP "" 0 +. +.P +Or you can set the credentials as an environment variable like this: +. +.IP "" 4 +. +.nf + +export BUNDLE_GEMS__LONGEROUS__COM="claudette:s00pers3krit" +. +.fi +. +.IP "" 0 +. +.P +For gems with a git source with HTTP(S) URL you can specify credentials like so: +. +.IP "" 4 +. +.nf + +bundle config set \-\-global https://github\.com/rubygems/rubygems\.git username:password +. +.fi +. +.IP "" 0 +. +.P +Or you can set the credentials as an environment variable like so: +. +.IP "" 4 +. +.nf + +export BUNDLE_GITHUB__COM=username:password +. +.fi +. +.IP "" 0 +. +.P +This is especially useful for private repositories on hosts such as GitHub, where you can use personal OAuth tokens: +. +.IP "" 4 +. +.nf + +export BUNDLE_GITHUB__COM=abcd0123generatedtoken:x\-oauth\-basic +. +.fi +. +.IP "" 0 +. +.P +Note that any configured credentials will be redacted by informative commands such as \fBbundle config list\fR or \fBbundle config get\fR, unless you use the \fB\-\-parseable\fR flag\. This is to avoid unintentionally leaking credentials when copy\-pasting bundler output\. +. +.P +Also note that to guarantee a sane mapping between valid environment variable names and valid host names, bundler makes the following transformations: +. +.IP "\(bu" 4 +Any \fB\-\fR characters in a host name are mapped to a triple dash (\fB___\fR) in the corresponding environment variable\. +. +.IP "\(bu" 4 +Any \fB\.\fR characters in a host name are mapped to a double dash (\fB__\fR) in the corresponding environment variable\. +. +.IP "" 0 +. +.P +This means that if you have a gem server named \fBmy\.gem\-host\.com\fR, you\'ll need to use the \fBBUNDLE_MY__GEM___HOST__COM\fR variable to configure credentials for it through ENV\. +. +.SH "CONFIGURE BUNDLER DIRECTORIES" +Bundler\'s home, config, cache and plugin directories are able to be configured through environment variables\. The default location for Bundler\'s home directory is \fB~/\.bundle\fR, which all directories inherit from by default\. The following outlines the available environment variables and their default values +. +.IP "" 4 +. +.nf + +BUNDLE_USER_HOME : $HOME/\.bundle +BUNDLE_USER_CACHE : $BUNDLE_USER_HOME/cache +BUNDLE_USER_CONFIG : $BUNDLE_USER_HOME/config +BUNDLE_USER_PLUGIN : $BUNDLE_USER_HOME/plugin +. +.fi +. +.IP "" 0 + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-config.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-config.1.ronn new file mode 100644 index 0000000..6f9edc9 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-config.1.ronn @@ -0,0 +1,408 @@ +bundle-config(1) -- Set bundler configuration options +===================================================== + +## SYNOPSIS + +`bundle config` list
    +`bundle config` [get] NAME
    +`bundle config` [set] NAME VALUE
    +`bundle config` unset NAME + +## DESCRIPTION + +This command allows you to interact with Bundler's configuration system. + +Bundler loads configuration settings in this order: + +1. Local config (`/.bundle/config` or `$BUNDLE_APP_CONFIG/config`) +2. Environmental variables (`ENV`) +3. Global config (`~/.bundle/config`) +4. Bundler default config + +Executing `bundle config list` with will print a list of all bundler +configuration for the current bundle, and where that configuration +was set. + +Executing `bundle config get ` will print the value of that configuration +setting, and where it was set. + +Executing `bundle config set ` defaults to setting `local` +configuration if executing from within a local application, otherwise it will +set `global` configuration. See `--local` and `--global` options below. + +Executing `bundle config set --local ` will set that configuration +in the directory for the local application. The configuration will be stored in +`/.bundle/config`. If `BUNDLE_APP_CONFIG` is set, the configuration +will be stored in `$BUNDLE_APP_CONFIG/config`. + +Executing `bundle config set --global ` will set that +configuration to the value specified for all bundles executed as the current +user. The configuration will be stored in `~/.bundle/config`. If already +is set, will be overridden and user will be warned. + +Executing `bundle config unset ` will delete the configuration in both +local and global sources. + +Executing `bundle config unset --global ` will delete the configuration +only from the user configuration. + +Executing `bundle config unset --local ` will delete the configuration +only from the local application. + +Executing bundle with the `BUNDLE_IGNORE_CONFIG` environment variable set will +cause it to ignore all configuration. + +## REMEMBERING OPTIONS + +Flags passed to `bundle install` or the Bundler runtime, such as `--path foo` or +`--without production`, are remembered between commands and saved to your local +application's configuration (normally, `./.bundle/config`). + +However, this will be changed in bundler 3, so it's better not to rely on this +behavior. If these options must be remembered, it's better to set them using +`bundle config` (e.g., `bundle config set --local path foo`). + +The options that can be configured are: + +* `bin`: + Creates a directory (defaults to `~/bin`) and place any executables from the + gem there. These executables run in Bundler's context. If used, you might add + this directory to your environment's `PATH` variable. For instance, if the + `rails` gem comes with a `rails` executable, this flag will create a + `bin/rails` executable that ensures that all referred dependencies will be + resolved using the bundled gems. + +* `deployment`: + In deployment mode, Bundler will 'roll-out' the bundle for + `production` use. Please check carefully if you want to have this option + enabled in `development` or `test` environments. + +* `only`: + A space-separated list of groups to install only gems of the specified groups. + +* `path`: + The location to install the specified gems to. This defaults to Rubygems' + setting. Bundler shares this location with Rubygems, `gem install ...` will + have gem installed there, too. Therefore, gems installed without a + `--path ...` setting will show up by calling `gem list`. Accordingly, gems + installed to other locations will not get listed. + +* `without`: + A space-separated list of groups referencing gems to skip during installation. + +* `with`: + A space-separated list of **optional** groups referencing gems to include during installation. + +## BUILD OPTIONS + +You can use `bundle config` to give Bundler the flags to pass to the gem +installer every time bundler tries to install a particular gem. + +A very common example, the `mysql` gem, requires Snow Leopard users to +pass configuration flags to `gem install` to specify where to find the +`mysql_config` executable. + + gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config + +Since the specific location of that executable can change from machine +to machine, you can specify these flags on a per-machine basis. + + bundle config set --global build.mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config + +After running this command, every time bundler needs to install the +`mysql` gem, it will pass along the flags you specified. + +## CONFIGURATION KEYS + +Configuration keys in bundler have two forms: the canonical form and the +environment variable form. + +For instance, passing the `--without` flag to [bundle install(1)](bundle-install.1.html) +prevents Bundler from installing certain groups specified in the Gemfile(5). Bundler +persists this value in `app/.bundle/config` so that calls to `Bundler.setup` +do not try to find gems from the `Gemfile` that you didn't install. Additionally, +subsequent calls to [bundle install(1)](bundle-install.1.html) remember this setting +and skip those groups. + +The canonical form of this configuration is `"without"`. To convert the canonical +form to the environment variable form, capitalize it, and prepend `BUNDLE_`. The +environment variable form of `"without"` is `BUNDLE_WITHOUT`. + +Any periods in the configuration keys must be replaced with two underscores when +setting it via environment variables. The configuration key `local.rack` becomes +the environment variable `BUNDLE_LOCAL__RACK`. + +## LIST OF AVAILABLE KEYS + +The following is a list of all configuration keys and their purpose. You can +learn more about their operation in [bundle install(1)](bundle-install.1.html). + +* `allow_deployment_source_credential_changes` (`BUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES`): + When in deployment mode, allow changing the credentials to a gem's source. + Ex: `https://some.host.com/gems/path/` -> `https://user_name:password@some.host.com/gems/path` +* `allow_offline_install` (`BUNDLE_ALLOW_OFFLINE_INSTALL`): + Allow Bundler to use cached data when installing without network access. +* `auto_clean_without_path` (`BUNDLE_AUTO_CLEAN_WITHOUT_PATH`): + Automatically run `bundle clean` after installing when an explicit `path` + has not been set and Bundler is not installing into the system gems. +* `auto_install` (`BUNDLE_AUTO_INSTALL`): + Automatically run `bundle install` when gems are missing. +* `bin` (`BUNDLE_BIN`): + Install executables from gems in the bundle to the specified directory. + Defaults to `false`. +* `cache_all` (`BUNDLE_CACHE_ALL`): + Cache all gems, including path and git gems. This needs to be explicitly + configured on bundler 1 and bundler 2, but will be the default on bundler 3. +* `cache_all_platforms` (`BUNDLE_CACHE_ALL_PLATFORMS`): + Cache gems for all platforms. +* `cache_path` (`BUNDLE_CACHE_PATH`): + The directory that bundler will place cached gems in when running + bundle package, and that bundler will look in when installing gems. + Defaults to `vendor/cache`. +* `clean` (`BUNDLE_CLEAN`): + Whether Bundler should run `bundle clean` automatically after + `bundle install`. +* `console` (`BUNDLE_CONSOLE`): + The console that `bundle console` starts. Defaults to `irb`. +* `default_install_uses_path` (`BUNDLE_DEFAULT_INSTALL_USES_PATH`): + Whether a `bundle install` without an explicit `--path` argument defaults + to installing gems in `.bundle`. +* `deployment` (`BUNDLE_DEPLOYMENT`): + Disallow changes to the `Gemfile`. When the `Gemfile` is changed and the + lockfile has not been updated, running Bundler commands will be blocked. +* `disable_checksum_validation` (`BUNDLE_DISABLE_CHECKSUM_VALIDATION`): + Allow installing gems even if they do not match the checksum provided by + RubyGems. +* `disable_exec_load` (`BUNDLE_DISABLE_EXEC_LOAD`): + Stop Bundler from using `load` to launch an executable in-process in + `bundle exec`. +* `disable_local_branch_check` (`BUNDLE_DISABLE_LOCAL_BRANCH_CHECK`): + Allow Bundler to use a local git override without a branch specified in the + Gemfile. +* `disable_local_revision_check` (`BUNDLE_DISABLE_LOCAL_REVISION_CHECK`): + Allow Bundler to use a local git override without checking if the revision + present in the lockfile is present in the repository. +* `disable_shared_gems` (`BUNDLE_DISABLE_SHARED_GEMS`): + Stop Bundler from accessing gems installed to RubyGems' normal location. +* `disable_version_check` (`BUNDLE_DISABLE_VERSION_CHECK`): + Stop Bundler from checking if a newer Bundler version is available on + rubygems.org. +* `force_ruby_platform` (`BUNDLE_FORCE_RUBY_PLATFORM`): + Ignore the current machine's platform and install only `ruby` platform gems. + As a result, gems with native extensions will be compiled from source. +* `frozen` (`BUNDLE_FROZEN`): + Disallow changes to the `Gemfile`. When the `Gemfile` is changed and the + lockfile has not been updated, running Bundler commands will be blocked. + Defaults to `true` when `--deployment` is used. +* `gem.github_username` (`BUNDLE_GEM__GITHUB_USERNAME`): + Sets a GitHub username or organization to be used in `README` file when you + create a new gem via `bundle gem` command. It can be overridden by passing an + explicit `--github-username` flag to `bundle gem`. +* `gem.push_key` (`BUNDLE_GEM__PUSH_KEY`): + Sets the `--key` parameter for `gem push` when using the `rake release` + command with a private gemstash server. +* `gemfile` (`BUNDLE_GEMFILE`): + The name of the file that bundler should use as the `Gemfile`. This location + of this file also sets the root of the project, which is used to resolve + relative paths in the `Gemfile`, among other things. By default, bundler + will search up from the current working directory until it finds a + `Gemfile`. +* `global_gem_cache` (`BUNDLE_GLOBAL_GEM_CACHE`): + Whether Bundler should cache all gems globally, rather than locally to the + installing Ruby installation. +* `ignore_funding_requests` (`BUNDLE_IGNORE_FUNDING_REQUESTS`): + When set, no funding requests will be printed. +* `ignore_messages` (`BUNDLE_IGNORE_MESSAGES`): + When set, no post install messages will be printed. To silence a single gem, + use dot notation like `ignore_messages.httparty true`. +* `init_gems_rb` (`BUNDLE_INIT_GEMS_RB`): + Generate a `gems.rb` instead of a `Gemfile` when running `bundle init`. +* `jobs` (`BUNDLE_JOBS`): + The number of gems Bundler can install in parallel. Defaults to the number of + available processors. +* `no_install` (`BUNDLE_NO_INSTALL`): + Whether `bundle package` should skip installing gems. +* `no_prune` (`BUNDLE_NO_PRUNE`): + Whether Bundler should leave outdated gems unpruned when caching. +* `only` (`BUNDLE_ONLY`): + A space-separated list of groups to install only gems of the specified groups. +* `path` (`BUNDLE_PATH`): + The location on disk where all gems in your bundle will be located regardless + of `$GEM_HOME` or `$GEM_PATH` values. Bundle gems not found in this location + will be installed by `bundle install`. Defaults to `Gem.dir`. When --deployment + is used, defaults to vendor/bundle. +* `path.system` (`BUNDLE_PATH__SYSTEM`): + Whether Bundler will install gems into the default system path (`Gem.dir`). +* `path_relative_to_cwd` (`BUNDLE_PATH_RELATIVE_TO_CWD`) + Makes `--path` relative to the CWD instead of the `Gemfile`. +* `plugins` (`BUNDLE_PLUGINS`): + Enable Bundler's experimental plugin system. +* `prefer_patch` (BUNDLE_PREFER_PATCH): + Prefer updating only to next patch version during updates. Makes `bundle update` calls equivalent to `bundler update --patch`. +* `print_only_version_number` (`BUNDLE_PRINT_ONLY_VERSION_NUMBER`): + Print only version number from `bundler --version`. +* `redirect` (`BUNDLE_REDIRECT`): + The number of redirects allowed for network requests. Defaults to `5`. +* `retry` (`BUNDLE_RETRY`): + The number of times to retry failed network requests. Defaults to `3`. +* `setup_makes_kernel_gem_public` (`BUNDLE_SETUP_MAKES_KERNEL_GEM_PUBLIC`): + Have `Bundler.setup` make the `Kernel#gem` method public, even though + RubyGems declares it as private. +* `shebang` (`BUNDLE_SHEBANG`): + The program name that should be invoked for generated binstubs. Defaults to + the ruby install name used to generate the binstub. +* `silence_deprecations` (`BUNDLE_SILENCE_DEPRECATIONS`): + Whether Bundler should silence deprecation warnings for behavior that will + be changed in the next major version. +* `silence_root_warning` (`BUNDLE_SILENCE_ROOT_WARNING`): + Silence the warning Bundler prints when installing gems as root. +* `ssl_ca_cert` (`BUNDLE_SSL_CA_CERT`): + Path to a designated CA certificate file or folder containing multiple + certificates for trusted CAs in PEM format. +* `ssl_client_cert` (`BUNDLE_SSL_CLIENT_CERT`): + Path to a designated file containing a X.509 client certificate + and key in PEM format. +* `ssl_verify_mode` (`BUNDLE_SSL_VERIFY_MODE`): + The SSL verification mode Bundler uses when making HTTPS requests. + Defaults to verify peer. +* `suppress_install_using_messages` (`BUNDLE_SUPPRESS_INSTALL_USING_MESSAGES`): + Avoid printing `Using ...` messages during installation when the version of + a gem has not changed. +* `system_bindir` (`BUNDLE_SYSTEM_BINDIR`): + The location where RubyGems installs binstubs. Defaults to `Gem.bindir`. +* `timeout` (`BUNDLE_TIMEOUT`): + The seconds allowed before timing out for network requests. Defaults to `10`. +* `update_requires_all_flag` (`BUNDLE_UPDATE_REQUIRES_ALL_FLAG`): + Require passing `--all` to `bundle update` when everything should be updated, + and disallow passing no options to `bundle update`. +* `user_agent` (`BUNDLE_USER_AGENT`): + The custom user agent fragment Bundler includes in API requests. +* `with` (`BUNDLE_WITH`): + A `:`-separated list of groups whose gems bundler should install. +* `without` (`BUNDLE_WITHOUT`): + A `:`-separated list of groups whose gems bundler should not install. + +In general, you should set these settings per-application by using the applicable +flag to the [bundle install(1)](bundle-install.1.html) or [bundle cache(1)](bundle-cache.1.html) command. + +You can set them globally either via environment variables or `bundle config`, +whichever is preferable for your setup. If you use both, environment variables +will take preference over global settings. + +## LOCAL GIT REPOS + +Bundler also allows you to work against a git repository locally +instead of using the remote version. This can be achieved by setting +up a local override: + + bundle config set --local local.GEM_NAME /path/to/local/git/repository + +For example, in order to use a local Rack repository, a developer could call: + + bundle config set --local local.rack ~/Work/git/rack + +Now instead of checking out the remote git repository, the local +override will be used. Similar to a path source, every time the local +git repository change, changes will be automatically picked up by +Bundler. This means a commit in the local git repo will update the +revision in the `Gemfile.lock` to the local git repo revision. This +requires the same attention as git submodules. Before pushing to +the remote, you need to ensure the local override was pushed, otherwise +you may point to a commit that only exists in your local machine. +You'll also need to CGI escape your usernames and passwords as well. + +Bundler does many checks to ensure a developer won't work with +invalid references. Particularly, we force a developer to specify +a branch in the `Gemfile` in order to use this feature. If the branch +specified in the `Gemfile` and the current branch in the local git +repository do not match, Bundler will abort. This ensures that +a developer is always working against the correct branches, and prevents +accidental locking to a different branch. + +Finally, Bundler also ensures that the current revision in the +`Gemfile.lock` exists in the local git repository. By doing this, Bundler +forces you to fetch the latest changes in the remotes. + +## MIRRORS OF GEM SOURCES + +Bundler supports overriding gem sources with mirrors. This allows you to +configure rubygems.org as the gem source in your Gemfile while still using your +mirror to fetch gems. + + bundle config set --global mirror.SOURCE_URL MIRROR_URL + +For example, to use a mirror of https://rubygems.org hosted at https://example.org: + + bundle config set --global mirror.https://rubygems.org https://example.org + +Each mirror also provides a fallback timeout setting. If the mirror does not +respond within the fallback timeout, Bundler will try to use the original +server instead of the mirror. + + bundle config set --global mirror.SOURCE_URL.fallback_timeout TIMEOUT + +For example, to fall back to rubygems.org after 3 seconds: + + bundle config set --global mirror.https://rubygems.org.fallback_timeout 3 + +The default fallback timeout is 0.1 seconds, but the setting can currently +only accept whole seconds (for example, 1, 15, or 30). + +## CREDENTIALS FOR GEM SOURCES + +Bundler allows you to configure credentials for any gem source, which allows +you to avoid putting secrets into your Gemfile. + + bundle config set --global SOURCE_HOSTNAME USERNAME:PASSWORD + +For example, to save the credentials of user `claudette` for the gem source at +`gems.longerous.com`, you would run: + + bundle config set --global gems.longerous.com claudette:s00pers3krit + +Or you can set the credentials as an environment variable like this: + + export BUNDLE_GEMS__LONGEROUS__COM="claudette:s00pers3krit" + +For gems with a git source with HTTP(S) URL you can specify credentials like so: + + bundle config set --global https://github.com/rubygems/rubygems.git username:password + +Or you can set the credentials as an environment variable like so: + + export BUNDLE_GITHUB__COM=username:password + +This is especially useful for private repositories on hosts such as GitHub, +where you can use personal OAuth tokens: + + export BUNDLE_GITHUB__COM=abcd0123generatedtoken:x-oauth-basic + +Note that any configured credentials will be redacted by informative commands +such as `bundle config list` or `bundle config get`, unless you use the +`--parseable` flag. This is to avoid unintentionally leaking credentials when +copy-pasting bundler output. + +Also note that to guarantee a sane mapping between valid environment variable +names and valid host names, bundler makes the following transformations: + +* Any `-` characters in a host name are mapped to a triple dash (`___`) in the + corresponding environment variable. + +* Any `.` characters in a host name are mapped to a double dash (`__`) in the + corresponding environment variable. + +This means that if you have a gem server named `my.gem-host.com`, you'll need to +use the `BUNDLE_MY__GEM___HOST__COM` variable to configure credentials for it +through ENV. + +## CONFIGURE BUNDLER DIRECTORIES + +Bundler's home, config, cache and plugin directories are able to be configured +through environment variables. The default location for Bundler's home directory is +`~/.bundle`, which all directories inherit from by default. The following +outlines the available environment variables and their default values + + BUNDLE_USER_HOME : $HOME/.bundle + BUNDLE_USER_CACHE : $BUNDLE_USER_HOME/cache + BUNDLE_USER_CONFIG : $BUNDLE_USER_HOME/config + BUNDLE_USER_PLUGIN : $BUNDLE_USER_HOME/plugin diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-console.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-console.1 new file mode 100644 index 0000000..c9463e3 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-console.1 @@ -0,0 +1,53 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-CONSOLE" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-console\fR \- Deprecated way to open an IRB session with the bundle pre\-loaded +. +.SH "SYNOPSIS" +\fBbundle console\fR [GROUP] +. +.SH "DESCRIPTION" +Starts an interactive Ruby console session in the context of the current bundle\. +. +.P +If no \fBGROUP\fR is specified, all gems in the \fBdefault\fR group in the Gemfile(5) \fIhttps://bundler\.io/man/gemfile\.5\.html\fR are preliminarily loaded\. +. +.P +If \fBGROUP\fR is specified, all gems in the given group in the Gemfile in addition to the gems in \fBdefault\fR group are loaded\. Even if the given group does not exist in the Gemfile, IRB console starts without any warning or error\. +. +.P +The environment variable \fBBUNDLE_CONSOLE\fR or \fBbundle config set console\fR can be used to change the shell from the following: +. +.IP "\(bu" 4 +\fBirb\fR (default) +. +.IP "\(bu" 4 +\fBpry\fR (https://github\.com/pry/pry) +. +.IP "\(bu" 4 +\fBripl\fR (https://github\.com/cldwalker/ripl) +. +.IP "" 0 +. +.P +\fBbundle console\fR uses irb by default\. An alternative Pry or Ripl can be used with \fBbundle console\fR by adjusting the \fBconsole\fR Bundler setting\. Also make sure that \fBpry\fR or \fBripl\fR is in your Gemfile\. +. +.SH "EXAMPLE" +. +.nf + +$ bundle config set console pry +$ bundle console +Resolving dependencies\.\.\. +[1] pry(main)> +. +.fi +. +.SH "NOTES" +This command was deprecated in Bundler 2\.1 and will be removed in 3\.0\. Use \fBbin/console\fR script, which can be generated by \fBbundle gem \fR\. +. +.SH "SEE ALSO" +Gemfile(5) \fIhttps://bundler\.io/man/gemfile\.5\.html\fR diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-console.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-console.1.ronn new file mode 100644 index 0000000..f9096d3 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-console.1.ronn @@ -0,0 +1,44 @@ +bundle-console(1) -- Deprecated way to open an IRB session with the bundle pre-loaded +===================================================================================== + +## SYNOPSIS + +`bundle console` [GROUP] + +## DESCRIPTION + +Starts an interactive Ruby console session in the context of the current bundle. + +If no `GROUP` is specified, all gems in the `default` group in the [Gemfile(5)](https://bundler.io/man/gemfile.5.html) are +preliminarily loaded. + +If `GROUP` is specified, all gems in the given group in the Gemfile in addition +to the gems in `default` group are loaded. Even if the given group does not +exist in the Gemfile, IRB console starts without any warning or error. + +The environment variable `BUNDLE_CONSOLE` or `bundle config set console` can be used to change +the shell from the following: + +* `irb` (default) +* `pry` (https://github.com/pry/pry) +* `ripl` (https://github.com/cldwalker/ripl) + +`bundle console` uses irb by default. An alternative Pry or Ripl can be used with +`bundle console` by adjusting the `console` Bundler setting. Also make sure that +`pry` or `ripl` is in your Gemfile. + +## EXAMPLE + + $ bundle config set console pry + $ bundle console + Resolving dependencies... + [1] pry(main)> + +## NOTES + +This command was deprecated in Bundler 2.1 and will be removed in 3.0. +Use `bin/console` script, which can be generated by `bundle gem `. + +## SEE ALSO + +[Gemfile(5)](https://bundler.io/man/gemfile.5.html) diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-doctor.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-doctor.1 new file mode 100644 index 0000000..dc5f5cf --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-doctor.1 @@ -0,0 +1,44 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-DOCTOR" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-doctor\fR \- Checks the bundle for common problems +. +.SH "SYNOPSIS" +\fBbundle doctor\fR [\-\-quiet] [\-\-gemfile=GEMFILE] +. +.SH "DESCRIPTION" +Checks your Gemfile and gem environment for common problems\. If issues are detected, Bundler prints them and exits status 1\. Otherwise, Bundler prints a success message and exits status 0\. +. +.P +Examples of common problems caught by bundle\-doctor include: +. +.IP "\(bu" 4 +Invalid Bundler settings +. +.IP "\(bu" 4 +Mismatched Ruby versions +. +.IP "\(bu" 4 +Mismatched platforms +. +.IP "\(bu" 4 +Uninstalled gems +. +.IP "\(bu" 4 +Missing dependencies +. +.IP "" 0 +. +.SH "OPTIONS" +. +.TP +\fB\-\-quiet\fR +Only output warnings and errors\. +. +.TP +\fB\-\-gemfile=\fR +The location of the Gemfile(5) which Bundler should use\. This defaults to a Gemfile(5) in the current working directory\. In general, Bundler will assume that the location of the Gemfile(5) is also the project\'s root and will try to find \fBGemfile\.lock\fR and \fBvendor/cache\fR relative to this location\. + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-doctor.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-doctor.1.ronn new file mode 100644 index 0000000..271ee80 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-doctor.1.ronn @@ -0,0 +1,33 @@ +bundle-doctor(1) -- Checks the bundle for common problems +========================================================= + +## SYNOPSIS + +`bundle doctor` [--quiet] + [--gemfile=GEMFILE] + +## DESCRIPTION + +Checks your Gemfile and gem environment for common problems. If issues +are detected, Bundler prints them and exits status 1. Otherwise, +Bundler prints a success message and exits status 0. + +Examples of common problems caught by bundle-doctor include: + +* Invalid Bundler settings +* Mismatched Ruby versions +* Mismatched platforms +* Uninstalled gems +* Missing dependencies + +## OPTIONS + +* `--quiet`: + Only output warnings and errors. + +* `--gemfile=`: + The location of the Gemfile(5) which Bundler should use. This defaults + to a Gemfile(5) in the current working directory. In general, Bundler + will assume that the location of the Gemfile(5) is also the project's + root and will try to find `Gemfile.lock` and `vendor/cache` relative + to this location. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-exec.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-exec.1 new file mode 100644 index 0000000..1b3ad11 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-exec.1 @@ -0,0 +1,165 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-EXEC" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-exec\fR \- Execute a command in the context of the bundle +. +.SH "SYNOPSIS" +\fBbundle exec\fR [\-\-keep\-file\-descriptors] \fIcommand\fR +. +.SH "DESCRIPTION" +This command executes the command, making all gems specified in the [\fBGemfile(5)\fR][Gemfile(5)] available to \fBrequire\fR in Ruby programs\. +. +.P +Essentially, if you would normally have run something like \fBrspec spec/my_spec\.rb\fR, and you want to use the gems specified in the [\fBGemfile(5)\fR][Gemfile(5)] and installed via bundle install(1) \fIbundle\-install\.1\.html\fR, you should run \fBbundle exec rspec spec/my_spec\.rb\fR\. +. +.P +Note that \fBbundle exec\fR does not require that an executable is available on your shell\'s \fB$PATH\fR\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-keep\-file\-descriptors\fR +Exec in Ruby 2\.0 began discarding non\-standard file descriptors\. When this flag is passed, exec will revert to the 1\.9 behaviour of passing all file descriptors to the new process\. +. +.SH "BUNDLE INSTALL \-\-BINSTUBS" +If you use the \fB\-\-binstubs\fR flag in bundle install(1) \fIbundle\-install\.1\.html\fR, Bundler will automatically create a directory (which defaults to \fBapp_root/bin\fR) containing all of the executables available from gems in the bundle\. +. +.P +After using \fB\-\-binstubs\fR, \fBbin/rspec spec/my_spec\.rb\fR is identical to \fBbundle exec rspec spec/my_spec\.rb\fR\. +. +.SH "ENVIRONMENT MODIFICATIONS" +\fBbundle exec\fR makes a number of changes to the shell environment, then executes the command you specify in full\. +. +.IP "\(bu" 4 +make sure that it\'s still possible to shell out to \fBbundle\fR from inside a command invoked by \fBbundle exec\fR (using \fB$BUNDLE_BIN_PATH\fR) +. +.IP "\(bu" 4 +put the directory containing executables (like \fBrails\fR, \fBrspec\fR, \fBrackup\fR) for your bundle on \fB$PATH\fR +. +.IP "\(bu" 4 +make sure that if bundler is invoked in the subshell, it uses the same \fBGemfile\fR (by setting \fBBUNDLE_GEMFILE\fR) +. +.IP "\(bu" 4 +add \fB\-rbundler/setup\fR to \fB$RUBYOPT\fR, which makes sure that Ruby programs invoked in the subshell can see the gems in the bundle +. +.IP "" 0 +. +.P +It also modifies Rubygems: +. +.IP "\(bu" 4 +disallow loading additional gems not in the bundle +. +.IP "\(bu" 4 +modify the \fBgem\fR method to be a no\-op if a gem matching the requirements is in the bundle, and to raise a \fBGem::LoadError\fR if it\'s not +. +.IP "\(bu" 4 +Define \fBGem\.refresh\fR to be a no\-op, since the source index is always frozen when using bundler, and to prevent gems from the system leaking into the environment +. +.IP "\(bu" 4 +Override \fBGem\.bin_path\fR to use the gems in the bundle, making system executables work +. +.IP "\(bu" 4 +Add all gems in the bundle into Gem\.loaded_specs +. +.IP "" 0 +. +.P +Finally, \fBbundle exec\fR also implicitly modifies \fBGemfile\.lock\fR if the lockfile and the Gemfile do not match\. Bundler needs the Gemfile to determine things such as a gem\'s groups, \fBautorequire\fR, and platforms, etc\., and that information isn\'t stored in the lockfile\. The Gemfile and lockfile must be synced in order to \fBbundle exec\fR successfully, so \fBbundle exec\fR updates the lockfile beforehand\. +. +.SS "Loading" +By default, when attempting to \fBbundle exec\fR to a file with a ruby shebang, Bundler will \fBKernel\.load\fR that file instead of using \fBKernel\.exec\fR\. For the vast majority of cases, this is a performance improvement\. In a rare few cases, this could cause some subtle side\-effects (such as dependence on the exact contents of \fB$0\fR or \fB__FILE__\fR) and the optimization can be disabled by enabling the \fBdisable_exec_load\fR setting\. +. +.SS "Shelling out" +Any Ruby code that opens a subshell (like \fBsystem\fR, backticks, or \fB%x{}\fR) will automatically use the current Bundler environment\. If you need to shell out to a Ruby command that is not part of your current bundle, use the \fBwith_clean_env\fR method with a block\. Any subshells created inside the block will be given the environment present before Bundler was activated\. For example, Homebrew commands run Ruby, but don\'t work inside a bundle: +. +.IP "" 4 +. +.nf + +Bundler\.with_clean_env do + `brew install wget` +end +. +.fi +. +.IP "" 0 +. +.P +Using \fBwith_clean_env\fR is also necessary if you are shelling out to a different bundle\. Any Bundler commands run in a subshell will inherit the current Gemfile, so commands that need to run in the context of a different bundle also need to use \fBwith_clean_env\fR\. +. +.IP "" 4 +. +.nf + +Bundler\.with_clean_env do + Dir\.chdir "/other/bundler/project" do + `bundle exec \./script` + end +end +. +.fi +. +.IP "" 0 +. +.P +Bundler provides convenience helpers that wrap \fBsystem\fR and \fBexec\fR, and they can be used like this: +. +.IP "" 4 +. +.nf + +Bundler\.clean_system(\'brew install wget\') +Bundler\.clean_exec(\'brew install wget\') +. +.fi +. +.IP "" 0 +. +.SH "RUBYGEMS PLUGINS" +At present, the Rubygems plugin system requires all files named \fBrubygems_plugin\.rb\fR on the load path of \fIany\fR installed gem when any Ruby code requires \fBrubygems\.rb\fR\. This includes executables installed into the system, like \fBrails\fR, \fBrackup\fR, and \fBrspec\fR\. +. +.P +Since Rubygems plugins can contain arbitrary Ruby code, they commonly end up activating themselves or their dependencies\. +. +.P +For instance, the \fBgemcutter 0\.5\fR gem depended on \fBjson_pure\fR\. If you had that version of gemcutter installed (even if you \fIalso\fR had a newer version without this problem), Rubygems would activate \fBgemcutter 0\.5\fR and \fBjson_pure \fR\. +. +.P +If your Gemfile(5) also contained \fBjson_pure\fR (or a gem with a dependency on \fBjson_pure\fR), the latest version on your system might conflict with the version in your Gemfile(5), or the snapshot version in your \fBGemfile\.lock\fR\. +. +.P +If this happens, bundler will say: +. +.IP "" 4 +. +.nf + +You have already activated json_pure 1\.4\.6 but your Gemfile +requires json_pure 1\.4\.3\. Consider using bundle exec\. +. +.fi +. +.IP "" 0 +. +.P +In this situation, you almost certainly want to remove the underlying gem with the problematic gem plugin\. In general, the authors of these plugins (in this case, the \fBgemcutter\fR gem) have released newer versions that are more careful in their plugins\. +. +.P +You can find a list of all the gems containing gem plugins by running +. +.IP "" 4 +. +.nf + +ruby \-e "puts Gem\.find_files(\'rubygems_plugin\.rb\')" +. +.fi +. +.IP "" 0 +. +.P +At the very least, you should remove all but the newest version of each gem plugin, and also remove all gem plugins that you aren\'t using (\fBgem uninstall gem_name\fR)\. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-exec.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-exec.1.ronn new file mode 100644 index 0000000..5f5e78e --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-exec.1.ronn @@ -0,0 +1,152 @@ +bundle-exec(1) -- Execute a command in the context of the bundle +================================================================ + +## SYNOPSIS + +`bundle exec` [--keep-file-descriptors] + +## DESCRIPTION + +This command executes the command, making all gems specified in the +[`Gemfile(5)`][Gemfile(5)] available to `require` in Ruby programs. + +Essentially, if you would normally have run something like +`rspec spec/my_spec.rb`, and you want to use the gems specified +in the [`Gemfile(5)`][Gemfile(5)] and installed via [bundle install(1)](bundle-install.1.html), you +should run `bundle exec rspec spec/my_spec.rb`. + +Note that `bundle exec` does not require that an executable is +available on your shell's `$PATH`. + +## OPTIONS + +* `--keep-file-descriptors`: + Exec in Ruby 2.0 began discarding non-standard file descriptors. When this + flag is passed, exec will revert to the 1.9 behaviour of passing all file + descriptors to the new process. + +## BUNDLE INSTALL --BINSTUBS + +If you use the `--binstubs` flag in [bundle install(1)](bundle-install.1.html), Bundler will +automatically create a directory (which defaults to `app_root/bin`) +containing all of the executables available from gems in the bundle. + +After using `--binstubs`, `bin/rspec spec/my_spec.rb` is identical +to `bundle exec rspec spec/my_spec.rb`. + +## ENVIRONMENT MODIFICATIONS + +`bundle exec` makes a number of changes to the shell environment, +then executes the command you specify in full. + +* make sure that it's still possible to shell out to `bundle` + from inside a command invoked by `bundle exec` (using + `$BUNDLE_BIN_PATH`) +* put the directory containing executables (like `rails`, `rspec`, + `rackup`) for your bundle on `$PATH` +* make sure that if bundler is invoked in the subshell, it uses + the same `Gemfile` (by setting `BUNDLE_GEMFILE`) +* add `-rbundler/setup` to `$RUBYOPT`, which makes sure that + Ruby programs invoked in the subshell can see the gems in + the bundle + +It also modifies Rubygems: + +* disallow loading additional gems not in the bundle +* modify the `gem` method to be a no-op if a gem matching + the requirements is in the bundle, and to raise a + `Gem::LoadError` if it's not +* Define `Gem.refresh` to be a no-op, since the source + index is always frozen when using bundler, and to + prevent gems from the system leaking into the environment +* Override `Gem.bin_path` to use the gems in the bundle, + making system executables work +* Add all gems in the bundle into Gem.loaded_specs + +Finally, `bundle exec` also implicitly modifies `Gemfile.lock` if the lockfile +and the Gemfile do not match. Bundler needs the Gemfile to determine things +such as a gem's groups, `autorequire`, and platforms, etc., and that +information isn't stored in the lockfile. The Gemfile and lockfile must be +synced in order to `bundle exec` successfully, so `bundle exec` +updates the lockfile beforehand. + +### Loading + +By default, when attempting to `bundle exec` to a file with a ruby shebang, +Bundler will `Kernel.load` that file instead of using `Kernel.exec`. For the +vast majority of cases, this is a performance improvement. In a rare few cases, +this could cause some subtle side-effects (such as dependence on the exact +contents of `$0` or `__FILE__`) and the optimization can be disabled by enabling +the `disable_exec_load` setting. + +### Shelling out + +Any Ruby code that opens a subshell (like `system`, backticks, or `%x{}`) will +automatically use the current Bundler environment. If you need to shell out to +a Ruby command that is not part of your current bundle, use the +`with_clean_env` method with a block. Any subshells created inside the block +will be given the environment present before Bundler was activated. For +example, Homebrew commands run Ruby, but don't work inside a bundle: + + Bundler.with_clean_env do + `brew install wget` + end + +Using `with_clean_env` is also necessary if you are shelling out to a different +bundle. Any Bundler commands run in a subshell will inherit the current +Gemfile, so commands that need to run in the context of a different bundle also +need to use `with_clean_env`. + + Bundler.with_clean_env do + Dir.chdir "/other/bundler/project" do + `bundle exec ./script` + end + end + +Bundler provides convenience helpers that wrap `system` and `exec`, and they +can be used like this: + + Bundler.clean_system('brew install wget') + Bundler.clean_exec('brew install wget') + + +## RUBYGEMS PLUGINS + +At present, the Rubygems plugin system requires all files +named `rubygems_plugin.rb` on the load path of _any_ installed +gem when any Ruby code requires `rubygems.rb`. This includes +executables installed into the system, like `rails`, `rackup`, +and `rspec`. + +Since Rubygems plugins can contain arbitrary Ruby code, they +commonly end up activating themselves or their dependencies. + +For instance, the `gemcutter 0.5` gem depended on `json_pure`. +If you had that version of gemcutter installed (even if +you _also_ had a newer version without this problem), Rubygems +would activate `gemcutter 0.5` and `json_pure `. + +If your Gemfile(5) also contained `json_pure` (or a gem +with a dependency on `json_pure`), the latest version on +your system might conflict with the version in your +Gemfile(5), or the snapshot version in your `Gemfile.lock`. + +If this happens, bundler will say: + + You have already activated json_pure 1.4.6 but your Gemfile + requires json_pure 1.4.3. Consider using bundle exec. + +In this situation, you almost certainly want to remove the +underlying gem with the problematic gem plugin. In general, +the authors of these plugins (in this case, the `gemcutter` +gem) have released newer versions that are more careful in +their plugins. + +You can find a list of all the gems containing gem plugins +by running + + ruby -e "puts Gem.find_files('rubygems_plugin.rb')" + +At the very least, you should remove all but the newest +version of each gem plugin, and also remove all gem plugins +that you aren't using (`gem uninstall gem_name`). diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-gem.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-gem.1 new file mode 100644 index 0000000..b70cfbc --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-gem.1 @@ -0,0 +1,115 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-GEM" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem +. +.SH "SYNOPSIS" +\fBbundle gem\fR \fIGEM_NAME\fR \fIOPTIONS\fR +. +.SH "DESCRIPTION" +Generates a directory named \fBGEM_NAME\fR with a \fBRakefile\fR, \fBGEM_NAME\.gemspec\fR, and other supporting files and directories that can be used to develop a rubygem with that name\. +. +.P +Run \fBrake \-T\fR in the resulting project for a list of Rake tasks that can be used to test and publish the gem to rubygems\.org\. +. +.P +The generated project skeleton can be customized with OPTIONS, as explained below\. Note that these options can also be specified via Bundler\'s global configuration file using the following names: +. +.IP "\(bu" 4 +\fBgem\.coc\fR +. +.IP "\(bu" 4 +\fBgem\.mit\fR +. +.IP "\(bu" 4 +\fBgem\.test\fR +. +.IP "" 0 +. +.SH "OPTIONS" +. +.TP +\fB\-\-exe\fR or \fB\-b\fR or \fB\-\-bin\fR +Specify that Bundler should create a binary executable (as \fBexe/GEM_NAME\fR) in the generated rubygem project\. This binary will also be added to the \fBGEM_NAME\.gemspec\fR manifest\. This behavior is disabled by default\. +. +.TP +\fB\-\-no\-exe\fR +Do not create a binary (overrides \fB\-\-exe\fR specified in the global config)\. +. +.TP +\fB\-\-coc\fR +Add a \fBCODE_OF_CONDUCT\.md\fR file to the root of the generated project\. If this option is unspecified, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\. +. +.TP +\fB\-\-no\-coc\fR +Do not create a \fBCODE_OF_CONDUCT\.md\fR (overrides \fB\-\-coc\fR specified in the global config)\. +. +.TP +\fB\-\-ext\fR +Add boilerplate for C extension code to the generated project\. This behavior is disabled by default\. +. +.TP +\fB\-\-no\-ext\fR +Do not add C extension code (overrides \fB\-\-ext\fR specified in the global config)\. +. +.TP +\fB\-\-mit\fR +Add an MIT license to a \fBLICENSE\.txt\fR file in the root of the generated project\. Your name from the global git config is used for the copyright statement\. If this option is unspecified, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\. +. +.TP +\fB\-\-no\-mit\fR +Do not create a \fBLICENSE\.txt\fR (overrides \fB\-\-mit\fR specified in the global config)\. +. +.TP +\fB\-t\fR, \fB\-\-test=minitest\fR, \fB\-\-test=rspec\fR, \fB\-\-test=test\-unit\fR +Specify the test framework that Bundler should use when generating the project\. Acceptable values are \fBminitest\fR, \fBrspec\fR and \fBtest\-unit\fR\. The \fBGEM_NAME\.gemspec\fR will be configured and a skeleton test/spec directory will be created based on this option\. Given no option is specified: +. +.IP +When Bundler is configured to generate tests, this defaults to Bundler\'s global config setting \fBgem\.test\fR\. +. +.IP +When Bundler is configured to not generate tests, an interactive prompt will be displayed and the answer will be used for the current rubygem project\. +. +.IP +When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\. +. +.TP +\fB\-\-ci\fR, \fB\-\-ci=github\fR, \fB\-\-ci=travis\fR, \fB\-\-ci=gitlab\fR, \fB\-\-ci=circle\fR +Specify the continuous integration service that Bundler should use when generating the project\. Acceptable values are \fBgithub\fR, \fBtravis\fR, \fBgitlab\fR and \fBcircle\fR\. A configuration file will be generated in the project directory\. Given no option is specified: +. +.IP +When Bundler is configured to generate CI files, this defaults to Bundler\'s global config setting \fBgem\.ci\fR\. +. +.IP +When Bundler is configured to not generate CI files, an interactive prompt will be displayed and the answer will be used for the current rubygem project\. +. +.IP +When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\. +. +.TP +\fB\-\-linter\fR, \fB\-\-linter=rubocop\fR, \fB\-\-linter=standard\fR +Specify the linter and code formatter that Bundler should add to the project\'s development dependencies\. Acceptable values are \fBrubocop\fR and \fBstandard\fR\. A configuration file will be generated in the project directory\. Given no option is specified: +. +.IP +When Bundler is configured to add a linter, this defaults to Bundler\'s global config setting \fBgem\.linter\fR\. +. +.IP +When Bundler is configured not to add a linter, an interactive prompt will be displayed and the answer will be used for the current rubygem project\. +. +.IP +When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\. +. +.TP +\fB\-e\fR, \fB\-\-edit[=EDITOR]\fR +Open the resulting GEM_NAME\.gemspec in EDITOR, or the default editor if not specified\. The default is \fB$BUNDLER_EDITOR\fR, \fB$VISUAL\fR, or \fB$EDITOR\fR\. +. +.SH "SEE ALSO" +. +.IP "\(bu" 4 +bundle config(1) \fIbundle\-config\.1\.html\fR +. +.IP "" 0 + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-gem.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-gem.1.ronn new file mode 100644 index 0000000..61c741f --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-gem.1.ronn @@ -0,0 +1,117 @@ +bundle-gem(1) -- Generate a project skeleton for creating a rubygem +==================================================================== + +## SYNOPSIS + +`bundle gem` [OPTIONS] + +## DESCRIPTION + +Generates a directory named `GEM_NAME` with a `Rakefile`, `GEM_NAME.gemspec`, +and other supporting files and directories that can be used to develop a +rubygem with that name. + +Run `rake -T` in the resulting project for a list of Rake tasks that can be used +to test and publish the gem to rubygems.org. + +The generated project skeleton can be customized with OPTIONS, as explained +below. Note that these options can also be specified via Bundler's global +configuration file using the following names: + +* `gem.coc` +* `gem.mit` +* `gem.test` + +## OPTIONS + +* `--exe` or `-b` or `--bin`: + Specify that Bundler should create a binary executable (as `exe/GEM_NAME`) + in the generated rubygem project. This binary will also be added to the + `GEM_NAME.gemspec` manifest. This behavior is disabled by default. + +* `--no-exe`: + Do not create a binary (overrides `--exe` specified in the global config). + +* `--coc`: + Add a `CODE_OF_CONDUCT.md` file to the root of the generated project. If + this option is unspecified, an interactive prompt will be displayed and the + answer will be saved in Bundler's global config for future `bundle gem` use. + +* `--no-coc`: + Do not create a `CODE_OF_CONDUCT.md` (overrides `--coc` specified in the + global config). + +* `--ext`: + Add boilerplate for C extension code to the generated project. This behavior + is disabled by default. + +* `--no-ext`: + Do not add C extension code (overrides `--ext` specified in the global + config). + +* `--mit`: + Add an MIT license to a `LICENSE.txt` file in the root of the generated + project. Your name from the global git config is used for the copyright + statement. If this option is unspecified, an interactive prompt will be + displayed and the answer will be saved in Bundler's global config for future + `bundle gem` use. + +* `--no-mit`: + Do not create a `LICENSE.txt` (overrides `--mit` specified in the global + config). + +* `-t`, `--test=minitest`, `--test=rspec`, `--test=test-unit`: + Specify the test framework that Bundler should use when generating the + project. Acceptable values are `minitest`, `rspec` and `test-unit`. The + `GEM_NAME.gemspec` will be configured and a skeleton test/spec directory will + be created based on this option. Given no option is specified: + + When Bundler is configured to generate tests, this defaults to Bundler's + global config setting `gem.test`. + + When Bundler is configured to not generate tests, an interactive prompt will + be displayed and the answer will be used for the current rubygem project. + + When Bundler is unconfigured, an interactive prompt will be displayed and + the answer will be saved in Bundler's global config for future `bundle gem` + use. + +* `--ci`, `--ci=github`, `--ci=travis`, `--ci=gitlab`, `--ci=circle`: + Specify the continuous integration service that Bundler should use when + generating the project. Acceptable values are `github`, `travis`, `gitlab` + and `circle`. A configuration file will be generated in the project directory. + Given no option is specified: + + When Bundler is configured to generate CI files, this defaults to Bundler's + global config setting `gem.ci`. + + When Bundler is configured to not generate CI files, an interactive prompt + will be displayed and the answer will be used for the current rubygem project. + + When Bundler is unconfigured, an interactive prompt will be displayed and + the answer will be saved in Bundler's global config for future `bundle gem` + use. + +* `--linter`, `--linter=rubocop`, `--linter=standard`: + Specify the linter and code formatter that Bundler should add to the + project's development dependencies. Acceptable values are `rubocop` and + `standard`. A configuration file will be generated in the project directory. + Given no option is specified: + + When Bundler is configured to add a linter, this defaults to Bundler's + global config setting `gem.linter`. + + When Bundler is configured not to add a linter, an interactive prompt + will be displayed and the answer will be used for the current rubygem project. + + When Bundler is unconfigured, an interactive prompt will be displayed and + the answer will be saved in Bundler's global config for future `bundle gem` + use. + +* `-e`, `--edit[=EDITOR]`: + Open the resulting GEM_NAME.gemspec in EDITOR, or the default editor if not + specified. The default is `$BUNDLER_EDITOR`, `$VISUAL`, or `$EDITOR`. + +## SEE ALSO + +* [bundle config(1)](bundle-config.1.html) diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-help.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-help.1 new file mode 100644 index 0000000..bf378b0 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-help.1 @@ -0,0 +1,13 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-HELP" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-help\fR \- Displays detailed help for each subcommand +. +.SH "SYNOPSIS" +\fBbundle help\fR [COMMAND] +. +.SH "DESCRIPTION" +Displays detailed help for the given subcommand\. You can specify a single \fBCOMMAND\fR at the same time\. When \fBCOMMAND\fR is omitted, help for \fBhelp\fR command will be displayed\. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-help.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-help.1.ronn new file mode 100644 index 0000000..0e144ae --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-help.1.ronn @@ -0,0 +1,12 @@ +bundle-help(1) -- Displays detailed help for each subcommand +============================================================ + +## SYNOPSIS + +`bundle help` [COMMAND] + +## DESCRIPTION + +Displays detailed help for the given subcommand. +You can specify a single `COMMAND` at the same time. +When `COMMAND` is omitted, help for `help` command will be displayed. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-info.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-info.1 new file mode 100644 index 0000000..9445aec --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-info.1 @@ -0,0 +1,20 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-INFO" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-info\fR \- Show information for the given gem in your bundle +. +.SH "SYNOPSIS" +\fBbundle info\fR [GEM] [\-\-path] +. +.SH "DESCRIPTION" +Print the basic information about the provided GEM such as homepage, version, path and summary\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-path\fR +Print the path of the given gem + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-info.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-info.1.ronn new file mode 100644 index 0000000..47e457a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-info.1.ronn @@ -0,0 +1,17 @@ +bundle-info(1) -- Show information for the given gem in your bundle +========================================================================= + +## SYNOPSIS + +`bundle info` [GEM] + [--path] + +## DESCRIPTION + +Print the basic information about the provided GEM such as homepage, version, +path and summary. + +## OPTIONS + +* `--path`: +Print the path of the given gem diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-init.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-init.1 new file mode 100644 index 0000000..b80652d --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-init.1 @@ -0,0 +1,25 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-INIT" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-init\fR \- Generates a Gemfile into the current working directory +. +.SH "SYNOPSIS" +\fBbundle init\fR [\-\-gemspec=FILE] +. +.SH "DESCRIPTION" +Init generates a default [\fBGemfile(5)\fR][Gemfile(5)] in the current working directory\. When adding a [\fBGemfile(5)\fR][Gemfile(5)] to a gem with a gemspec, the \fB\-\-gemspec\fR option will automatically add each dependency listed in the gemspec file to the newly created [\fBGemfile(5)\fR][Gemfile(5)]\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-gemspec\fR +Use the specified \.gemspec to create the [\fBGemfile(5)\fR][Gemfile(5)] +. +.SH "FILES" +Included in the default [\fBGemfile(5)\fR][Gemfile(5)] generated is the line \fB# frozen_string_literal: true\fR\. This is a magic comment supported for the first time in Ruby 2\.3\. The presence of this line results in all string literals in the file being implicitly frozen\. +. +.SH "SEE ALSO" +Gemfile(5) \fIhttps://bundler\.io/man/gemfile\.5\.html\fR diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-init.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-init.1.ronn new file mode 100644 index 0000000..9d3d97d --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-init.1.ronn @@ -0,0 +1,29 @@ +bundle-init(1) -- Generates a Gemfile into the current working directory +======================================================================== + +## SYNOPSIS + +`bundle init` [--gemspec=FILE] + +## DESCRIPTION + +Init generates a default [`Gemfile(5)`][Gemfile(5)] in the current working directory. When +adding a [`Gemfile(5)`][Gemfile(5)] to a gem with a gemspec, the `--gemspec` option will +automatically add each dependency listed in the gemspec file to the newly +created [`Gemfile(5)`][Gemfile(5)]. + +## OPTIONS + +* `--gemspec`: + Use the specified .gemspec to create the [`Gemfile(5)`][Gemfile(5)] + +## FILES + +Included in the default [`Gemfile(5)`][Gemfile(5)] +generated is the line `# frozen_string_literal: true`. This is a magic comment +supported for the first time in Ruby 2.3. The presence of this line +results in all string literals in the file being implicitly frozen. + +## SEE ALSO + +[Gemfile(5)](https://bundler.io/man/gemfile.5.html) diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-inject.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-inject.1 new file mode 100644 index 0000000..bd440ee --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-inject.1 @@ -0,0 +1,36 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-INJECT" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile +. +.SH "SYNOPSIS" +\fBbundle inject\fR [GEM] [VERSION] +. +.SH "DESCRIPTION" +Adds the named gem(s) with their version requirements to the resolved [\fBGemfile(5)\fR][Gemfile(5)]\. +. +.P +This command will add the gem to both your [\fBGemfile(5)\fR][Gemfile(5)] and Gemfile\.lock if it isn\'t listed yet\. +. +.P +Example: +. +.IP "" 4 +. +.nf + +bundle install +bundle inject \'rack\' \'> 0\' +. +.fi +. +.IP "" 0 +. +.P +This will inject the \'rack\' gem with a version greater than 0 in your [\fBGemfile(5)\fR][Gemfile(5)] and Gemfile\.lock\. +. +.P +The \fBbundle inject\fR command was deprecated in Bundler 2\.1 and will be removed in Bundler 3\.0\. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-inject.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-inject.1.ronn new file mode 100644 index 0000000..95704ed --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-inject.1.ronn @@ -0,0 +1,24 @@ +bundle-inject(1) -- Add named gem(s) with version requirements to Gemfile +========================================================================= + +## SYNOPSIS + +`bundle inject` [GEM] [VERSION] + +## DESCRIPTION + +Adds the named gem(s) with their version requirements to the resolved +[`Gemfile(5)`][Gemfile(5)]. + +This command will add the gem to both your [`Gemfile(5)`][Gemfile(5)] and Gemfile.lock if it +isn't listed yet. + +Example: + + bundle install + bundle inject 'rack' '> 0' + +This will inject the 'rack' gem with a version greater than 0 in your +[`Gemfile(5)`][Gemfile(5)] and Gemfile.lock. + +The `bundle inject` command was deprecated in Bundler 2.1 and will be removed in Bundler 3.0. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-install.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-install.1 new file mode 100644 index 0000000..7a8555b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-install.1 @@ -0,0 +1,342 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-INSTALL" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile +. +.SH "SYNOPSIS" +\fBbundle install\fR [\-\-binstubs[=DIRECTORY]] [\-\-clean] [\-\-deployment] [\-\-frozen] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-jobs=NUMBER] [\-\-local] [\-\-no\-cache] [\-\-no\-prune] [\-\-path PATH] [\-\-quiet] [\-\-redownload] [\-\-retry=NUMBER] [\-\-shebang] [\-\-standalone[=GROUP[ GROUP\.\.\.]]] [\-\-system] [\-\-trust\-policy=POLICY] [\-\-with=GROUP[ GROUP\.\.\.]] [\-\-without=GROUP[ GROUP\.\.\.]] +. +.SH "DESCRIPTION" +Install the gems specified in your Gemfile(5)\. If this is the first time you run bundle install (and a \fBGemfile\.lock\fR does not exist), Bundler will fetch all remote sources, resolve dependencies and install all needed gems\. +. +.P +If a \fBGemfile\.lock\fR does exist, and you have not updated your Gemfile(5), Bundler will fetch all remote sources, but use the dependencies specified in the \fBGemfile\.lock\fR instead of resolving dependencies\. +. +.P +If a \fBGemfile\.lock\fR does exist, and you have updated your Gemfile(5), Bundler will use the dependencies in the \fBGemfile\.lock\fR for all gems that you did not update, but will re\-resolve the dependencies of gems that you did update\. You can find more information about this update process below under \fICONSERVATIVE UPDATING\fR\. +. +.SH "OPTIONS" +The \fB\-\-clean\fR, \fB\-\-deployment\fR, \fB\-\-frozen\fR, \fB\-\-no\-prune\fR, \fB\-\-path\fR, \fB\-\-shebang\fR, \fB\-\-system\fR, \fB\-\-without\fR and \fB\-\-with\fR options are deprecated because they only make sense if they are applied to every subsequent \fBbundle install\fR run automatically and that requires \fBbundler\fR to silently remember them\. Since \fBbundler\fR will no longer remember CLI flags in future versions, \fBbundle config\fR (see bundle\-config(1)) should be used to apply them permanently\. +. +.TP +\fB\-\-binstubs[=]\fR +Binstubs are scripts that wrap around executables\. Bundler creates a small Ruby file (a binstub) that loads Bundler, runs the command, and puts it in \fBbin/\fR\. This lets you link the binstub inside of an application to the exact gem version the application needs\. +. +.IP +Creates a directory (defaults to \fB~/bin\fR) and places any executables from the gem there\. These executables run in Bundler\'s context\. If used, you might add this directory to your environment\'s \fBPATH\fR variable\. For instance, if the \fBrails\fR gem comes with a \fBrails\fR executable, this flag will create a \fBbin/rails\fR executable that ensures that all referred dependencies will be resolved using the bundled gems\. +. +.TP +\fB\-\-clean\fR +On finishing the installation Bundler is going to remove any gems not present in the current Gemfile(5)\. Don\'t worry, gems currently in use will not be removed\. +. +.IP +This option is deprecated in favor of the \fBclean\fR setting\. +. +.TP +\fB\-\-deployment\fR +In \fIdeployment mode\fR, Bundler will \'roll\-out\' the bundle for production or CI use\. Please check carefully if you want to have this option enabled in your development environment\. +. +.IP +This option is deprecated in favor of the \fBdeployment\fR setting\. +. +.TP +\fB\-\-redownload\fR +Force download every gem, even if the required versions are already available locally\. +. +.TP +\fB\-\-frozen\fR +Do not allow the Gemfile\.lock to be updated after this install\. Exits non\-zero if there are going to be changes to the Gemfile\.lock\. +. +.IP +This option is deprecated in favor of the \fBfrozen\fR setting\. +. +.TP +\fB\-\-full\-index\fR +Bundler will not call Rubygems\' API endpoint (default) but download and cache a (currently big) index file of all gems\. Performance can be improved for large bundles that seldom change by enabling this option\. +. +.TP +\fB\-\-gemfile=\fR +The location of the Gemfile(5) which Bundler should use\. This defaults to a Gemfile(5) in the current working directory\. In general, Bundler will assume that the location of the Gemfile(5) is also the project\'s root and will try to find \fBGemfile\.lock\fR and \fBvendor/cache\fR relative to this location\. +. +.TP +\fB\-\-jobs=[]\fR, \fB\-j[]\fR +The maximum number of parallel download and install jobs\. The default is the number of available processors\. +. +.TP +\fB\-\-local\fR +Do not attempt to connect to \fBrubygems\.org\fR\. Instead, Bundler will use the gems already present in Rubygems\' cache or in \fBvendor/cache\fR\. Note that if an appropriate platform\-specific gem exists on \fBrubygems\.org\fR it will not be found\. +. +.TP +\fB\-\-prefer\-local\fR +Force using locally installed gems, or gems already present in Rubygems\' cache or in \fBvendor/cache\fR, when resolving, even if newer versions are available remotely\. Only attempt to connect to \fBrubygems\.org\fR for gems that are not present locally\. +. +.TP +\fB\-\-no\-cache\fR +Do not update the cache in \fBvendor/cache\fR with the newly bundled gems\. This does not remove any gems in the cache but keeps the newly bundled gems from being cached during the install\. +. +.TP +\fB\-\-no\-prune\fR +Don\'t remove stale gems from the cache when the installation finishes\. +. +.IP +This option is deprecated in favor of the \fBno_prune\fR setting\. +. +.TP +\fB\-\-path=\fR +The location to install the specified gems to\. This defaults to Rubygems\' setting\. Bundler shares this location with Rubygems, \fBgem install \.\.\.\fR will have gem installed there, too\. Therefore, gems installed without a \fB\-\-path \.\.\.\fR setting will show up by calling \fBgem list\fR\. Accordingly, gems installed to other locations will not get listed\. +. +.IP +This option is deprecated in favor of the \fBpath\fR setting\. +. +.TP +\fB\-\-quiet\fR +Do not print progress information to the standard output\. Instead, Bundler will exit using a status code (\fB$?\fR)\. +. +.TP +\fB\-\-retry=[]\fR +Retry failed network or git requests for \fInumber\fR times\. +. +.TP +\fB\-\-shebang=\fR +Uses the specified ruby executable (usually \fBruby\fR) to execute the scripts created with \fB\-\-binstubs\fR\. In addition, if you use \fB\-\-binstubs\fR together with \fB\-\-shebang jruby\fR these executables will be changed to execute \fBjruby\fR instead\. +. +.IP +This option is deprecated in favor of the \fBshebang\fR setting\. +. +.TP +\fB\-\-standalone[=]\fR +Makes a bundle that can work without depending on Rubygems or Bundler at runtime\. A space separated list of groups to install has to be specified\. Bundler creates a directory named \fBbundle\fR and installs the bundle there\. It also generates a \fBbundle/bundler/setup\.rb\fR file to replace Bundler\'s own setup in the manner required\. Using this option implicitly sets \fBpath\fR, which is a [remembered option][REMEMBERED OPTIONS]\. +. +.TP +\fB\-\-system\fR +Installs the gems specified in the bundle to the system\'s Rubygems location\. This overrides any previous configuration of \fB\-\-path\fR\. +. +.IP +This option is deprecated in favor of the \fBsystem\fR setting\. +. +.TP +\fB\-\-trust\-policy=[]\fR +Apply the Rubygems security policy \fIpolicy\fR, where policy is one of \fBHighSecurity\fR, \fBMediumSecurity\fR, \fBLowSecurity\fR, \fBAlmostNoSecurity\fR, or \fBNoSecurity\fR\. For more details, please see the Rubygems signing documentation linked below in \fISEE ALSO\fR\. +. +.TP +\fB\-\-with=\fR +A space\-separated list of groups referencing gems to install\. If an optional group is given it is installed\. If a group is given that is in the remembered list of groups given to \-\-without, it is removed from that list\. +. +.IP +This option is deprecated in favor of the \fBwith\fR setting\. +. +.TP +\fB\-\-without=\fR +A space\-separated list of groups referencing gems to skip during installation\. If a group is given that is in the remembered list of groups given to \-\-with, it is removed from that list\. +. +.IP +This option is deprecated in favor of the \fBwithout\fR setting\. +. +.SH "DEPLOYMENT MODE" +Bundler\'s defaults are optimized for development\. To switch to defaults optimized for deployment and for CI, use the \fB\-\-deployment\fR flag\. Do not activate deployment mode on development machines, as it will cause an error when the Gemfile(5) is modified\. +. +.IP "1." 4 +A \fBGemfile\.lock\fR is required\. +. +.IP +To ensure that the same versions of the gems you developed with and tested with are also used in deployments, a \fBGemfile\.lock\fR is required\. +. +.IP +This is mainly to ensure that you remember to check your \fBGemfile\.lock\fR into version control\. +. +.IP "2." 4 +The \fBGemfile\.lock\fR must be up to date +. +.IP +In development, you can modify your Gemfile(5) and re\-run \fBbundle install\fR to \fIconservatively update\fR your \fBGemfile\.lock\fR snapshot\. +. +.IP +In deployment, your \fBGemfile\.lock\fR should be up\-to\-date with changes made in your Gemfile(5)\. +. +.IP "3." 4 +Gems are installed to \fBvendor/bundle\fR not your default system location +. +.IP +In development, it\'s convenient to share the gems used in your application with other applications and other scripts that run on the system\. +. +.IP +In deployment, isolation is a more important default\. In addition, the user deploying the application may not have permission to install gems to the system, or the web server may not have permission to read them\. +. +.IP +As a result, \fBbundle install \-\-deployment\fR installs gems to the \fBvendor/bundle\fR directory in the application\. This may be overridden using the \fB\-\-path\fR option\. +. +.IP "" 0 +. +.SH "SUDO USAGE" +By default, Bundler installs gems to the same location as \fBgem install\fR\. +. +.P +In some cases, that location may not be writable by your Unix user\. In that case, Bundler will stage everything in a temporary directory, then ask you for your \fBsudo\fR password in order to copy the gems into their system location\. +. +.P +From your perspective, this is identical to installing the gems directly into the system\. +. +.P +You should never use \fBsudo bundle install\fR\. This is because several other steps in \fBbundle install\fR must be performed as the current user: +. +.IP "\(bu" 4 +Updating your \fBGemfile\.lock\fR +. +.IP "\(bu" 4 +Updating your \fBvendor/cache\fR, if necessary +. +.IP "\(bu" 4 +Checking out private git repositories using your user\'s SSH keys +. +.IP "" 0 +. +.P +Of these three, the first two could theoretically be performed by \fBchown\fRing the resulting files to \fB$SUDO_USER\fR\. The third, however, can only be performed by invoking the \fBgit\fR command as the current user\. Therefore, git gems are downloaded and installed into \fB~/\.bundle\fR rather than $GEM_HOME or $BUNDLE_PATH\. +. +.P +As a result, you should run \fBbundle install\fR as the current user, and Bundler will ask for your password if it is needed to put the gems into their final location\. +. +.SH "INSTALLING GROUPS" +By default, \fBbundle install\fR will install all gems in all groups in your Gemfile(5), except those declared for a different platform\. +. +.P +However, you can explicitly tell Bundler to skip installing certain groups with the \fB\-\-without\fR option\. This option takes a space\-separated list of groups\. +. +.P +While the \fB\-\-without\fR option will skip \fIinstalling\fR the gems in the specified groups, it will still \fIdownload\fR those gems and use them to resolve the dependencies of every gem in your Gemfile(5)\. +. +.P +This is so that installing a different set of groups on another machine (such as a production server) will not change the gems and versions that you have already developed and tested against\. +. +.P +\fBBundler offers a rock\-solid guarantee that the third\-party code you are running in development and testing is also the third\-party code you are running in production\. You can choose to exclude some of that code in different environments, but you will never be caught flat\-footed by different versions of third\-party code being used in different environments\.\fR +. +.P +For a simple illustration, consider the following Gemfile(5): +. +.IP "" 4 +. +.nf + +source \'https://rubygems\.org\' + +gem \'sinatra\' + +group :production do + gem \'rack\-perftools\-profiler\' +end +. +.fi +. +.IP "" 0 +. +.P +In this case, \fBsinatra\fR depends on any version of Rack (\fB>= 1\.0\fR), while \fBrack\-perftools\-profiler\fR depends on 1\.x (\fB~> 1\.0\fR)\. +. +.P +When you run \fBbundle install \-\-without production\fR in development, we look at the dependencies of \fBrack\-perftools\-profiler\fR as well\. That way, you do not spend all your time developing against Rack 2\.0, using new APIs unavailable in Rack 1\.x, only to have Bundler switch to Rack 1\.2 when the \fBproduction\fR group \fIis\fR used\. +. +.P +This should not cause any problems in practice, because we do not attempt to \fBinstall\fR the gems in the excluded groups, and only evaluate as part of the dependency resolution process\. +. +.P +This also means that you cannot include different versions of the same gem in different groups, because doing so would result in different sets of dependencies used in development and production\. Because of the vagaries of the dependency resolution process, this usually affects more than the gems you list in your Gemfile(5), and can (surprisingly) radically change the gems you are using\. +. +.SH "THE GEMFILE\.LOCK" +When you run \fBbundle install\fR, Bundler will persist the full names and versions of all gems that you used (including dependencies of the gems specified in the Gemfile(5)) into a file called \fBGemfile\.lock\fR\. +. +.P +Bundler uses this file in all subsequent calls to \fBbundle install\fR, which guarantees that you always use the same exact code, even as your application moves across machines\. +. +.P +Because of the way dependency resolution works, even a seemingly small change (for instance, an update to a point\-release of a dependency of a gem in your Gemfile(5)) can result in radically different gems being needed to satisfy all dependencies\. +. +.P +As a result, you \fBSHOULD\fR check your \fBGemfile\.lock\fR into version control, in both applications and gems\. If you do not, every machine that checks out your repository (including your production server) will resolve all dependencies again, which will result in different versions of third\-party code being used if \fBany\fR of the gems in the Gemfile(5) or any of their dependencies have been updated\. +. +.P +When Bundler first shipped, the \fBGemfile\.lock\fR was included in the \fB\.gitignore\fR file included with generated gems\. Over time, however, it became clear that this practice forces the pain of broken dependencies onto new contributors, while leaving existing contributors potentially unaware of the problem\. Since \fBbundle install\fR is usually the first step towards a contribution, the pain of broken dependencies would discourage new contributors from contributing\. As a result, we have revised our guidance for gem authors to now recommend checking in the lock for gems\. +. +.SH "CONSERVATIVE UPDATING" +When you make a change to the Gemfile(5) and then run \fBbundle install\fR, Bundler will update only the gems that you modified\. +. +.P +In other words, if a gem that you \fBdid not modify\fR worked before you called \fBbundle install\fR, it will continue to use the exact same versions of all dependencies as it used before the update\. +. +.P +Let\'s take a look at an example\. Here\'s your original Gemfile(5): +. +.IP "" 4 +. +.nf + +source \'https://rubygems\.org\' + +gem \'actionpack\', \'2\.3\.8\' +gem \'activemerchant\' +. +.fi +. +.IP "" 0 +. +.P +In this case, both \fBactionpack\fR and \fBactivemerchant\fR depend on \fBactivesupport\fR\. The \fBactionpack\fR gem depends on \fBactivesupport 2\.3\.8\fR and \fBrack ~> 1\.1\.0\fR, while the \fBactivemerchant\fR gem depends on \fBactivesupport >= 2\.3\.2\fR, \fBbraintree >= 2\.0\.0\fR, and \fBbuilder >= 2\.0\.0\fR\. +. +.P +When the dependencies are first resolved, Bundler will select \fBactivesupport 2\.3\.8\fR, which satisfies the requirements of both gems in your Gemfile(5)\. +. +.P +Next, you modify your Gemfile(5) to: +. +.IP "" 4 +. +.nf + +source \'https://rubygems\.org\' + +gem \'actionpack\', \'3\.0\.0\.rc\' +gem \'activemerchant\' +. +.fi +. +.IP "" 0 +. +.P +The \fBactionpack 3\.0\.0\.rc\fR gem has a number of new dependencies, and updates the \fBactivesupport\fR dependency to \fB= 3\.0\.0\.rc\fR and the \fBrack\fR dependency to \fB~> 1\.2\.1\fR\. +. +.P +When you run \fBbundle install\fR, Bundler notices that you changed the \fBactionpack\fR gem, but not the \fBactivemerchant\fR gem\. It evaluates the gems currently being used to satisfy its requirements: +. +.TP +\fBactivesupport 2\.3\.8\fR +also used to satisfy a dependency in \fBactivemerchant\fR, which is not being updated +. +.TP +\fBrack ~> 1\.1\.0\fR +not currently being used to satisfy another dependency +. +.P +Because you did not explicitly ask to update \fBactivemerchant\fR, you would not expect it to suddenly stop working after updating \fBactionpack\fR\. However, satisfying the new \fBactivesupport 3\.0\.0\.rc\fR dependency of actionpack requires updating one of its dependencies\. +. +.P +Even though \fBactivemerchant\fR declares a very loose dependency that theoretically matches \fBactivesupport 3\.0\.0\.rc\fR, Bundler treats gems in your Gemfile(5) that have not changed as an atomic unit together with their dependencies\. In this case, the \fBactivemerchant\fR dependency is treated as \fBactivemerchant 1\.7\.1 + activesupport 2\.3\.8\fR, so \fBbundle install\fR will report that it cannot update \fBactionpack\fR\. +. +.P +To explicitly update \fBactionpack\fR, including its dependencies which other gems in the Gemfile(5) still depend on, run \fBbundle update actionpack\fR (see \fBbundle update(1)\fR)\. +. +.P +\fBSummary\fR: In general, after making a change to the Gemfile(5) , you should first try to run \fBbundle install\fR, which will guarantee that no other gem in the Gemfile(5) is impacted by the change\. If that does not work, run bundle update(1) \fIbundle\-update\.1\.html\fR\. +. +.SH "SEE ALSO" +. +.IP "\(bu" 4 +Gem install docs \fIhttp://guides\.rubygems\.org/rubygems\-basics/#installing\-gems\fR +. +.IP "\(bu" 4 +Rubygems signing docs \fIhttp://guides\.rubygems\.org/security/\fR +. +.IP "" 0 + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-install.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-install.1.ronn new file mode 100644 index 0000000..47200ac --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-install.1.ronn @@ -0,0 +1,411 @@ +bundle-install(1) -- Install the dependencies specified in your Gemfile +======================================================================= + +## SYNOPSIS + +`bundle install` [--binstubs[=DIRECTORY]] + [--clean] + [--deployment] + [--frozen] + [--full-index] + [--gemfile=GEMFILE] + [--jobs=NUMBER] + [--local] + [--no-cache] + [--no-prune] + [--path PATH] + [--quiet] + [--redownload] + [--retry=NUMBER] + [--shebang] + [--standalone[=GROUP[ GROUP...]]] + [--system] + [--trust-policy=POLICY] + [--with=GROUP[ GROUP...]] + [--without=GROUP[ GROUP...]] + +## DESCRIPTION + +Install the gems specified in your Gemfile(5). If this is the first +time you run bundle install (and a `Gemfile.lock` does not exist), +Bundler will fetch all remote sources, resolve dependencies and +install all needed gems. + +If a `Gemfile.lock` does exist, and you have not updated your Gemfile(5), +Bundler will fetch all remote sources, but use the dependencies +specified in the `Gemfile.lock` instead of resolving dependencies. + +If a `Gemfile.lock` does exist, and you have updated your Gemfile(5), +Bundler will use the dependencies in the `Gemfile.lock` for all gems +that you did not update, but will re-resolve the dependencies of +gems that you did update. You can find more information about this +update process below under [CONSERVATIVE UPDATING][]. + +## OPTIONS + +The `--clean`, `--deployment`, `--frozen`, `--no-prune`, `--path`, `--shebang`, +`--system`, `--without` and `--with` options are deprecated because they only +make sense if they are applied to every subsequent `bundle install` run +automatically and that requires `bundler` to silently remember them. Since +`bundler` will no longer remember CLI flags in future versions, `bundle config` +(see bundle-config(1)) should be used to apply them permanently. + +* `--binstubs[=]`: + Binstubs are scripts that wrap around executables. Bundler creates a small Ruby + file (a binstub) that loads Bundler, runs the command, and puts it in `bin/`. + This lets you link the binstub inside of an application to the exact gem + version the application needs. + + Creates a directory (defaults to `~/bin`) and places any executables from the + gem there. These executables run in Bundler's context. If used, you might add + this directory to your environment's `PATH` variable. For instance, if the + `rails` gem comes with a `rails` executable, this flag will create a + `bin/rails` executable that ensures that all referred dependencies will be + resolved using the bundled gems. + +* `--clean`: + On finishing the installation Bundler is going to remove any gems not present + in the current Gemfile(5). Don't worry, gems currently in use will not be + removed. + + This option is deprecated in favor of the `clean` setting. + +* `--deployment`: + In [deployment mode][DEPLOYMENT MODE], Bundler will 'roll-out' the bundle for + production or CI use. Please check carefully if you want to have this option + enabled in your development environment. + + This option is deprecated in favor of the `deployment` setting. + +* `--redownload`: + Force download every gem, even if the required versions are already available + locally. + +* `--frozen`: + Do not allow the Gemfile.lock to be updated after this install. Exits + non-zero if there are going to be changes to the Gemfile.lock. + + This option is deprecated in favor of the `frozen` setting. + +* `--full-index`: + Bundler will not call Rubygems' API endpoint (default) but download and cache + a (currently big) index file of all gems. Performance can be improved for + large bundles that seldom change by enabling this option. + +* `--gemfile=`: + The location of the Gemfile(5) which Bundler should use. This defaults + to a Gemfile(5) in the current working directory. In general, Bundler + will assume that the location of the Gemfile(5) is also the project's + root and will try to find `Gemfile.lock` and `vendor/cache` relative + to this location. + +* `--jobs=[]`, `-j[]`: + The maximum number of parallel download and install jobs. The default is the + number of available processors. + +* `--local`: + Do not attempt to connect to `rubygems.org`. Instead, Bundler will use the + gems already present in Rubygems' cache or in `vendor/cache`. Note that if an + appropriate platform-specific gem exists on `rubygems.org` it will not be + found. + +* `--prefer-local`: + Force using locally installed gems, or gems already present in Rubygems' cache + or in `vendor/cache`, when resolving, even if newer versions are available + remotely. Only attempt to connect to `rubygems.org` for gems that are not + present locally. + +* `--no-cache`: + Do not update the cache in `vendor/cache` with the newly bundled gems. This + does not remove any gems in the cache but keeps the newly bundled gems from + being cached during the install. + +* `--no-prune`: + Don't remove stale gems from the cache when the installation finishes. + + This option is deprecated in favor of the `no_prune` setting. + +* `--path=`: + The location to install the specified gems to. This defaults to Rubygems' + setting. Bundler shares this location with Rubygems, `gem install ...` will + have gem installed there, too. Therefore, gems installed without a + `--path ...` setting will show up by calling `gem list`. Accordingly, gems + installed to other locations will not get listed. + + This option is deprecated in favor of the `path` setting. + +* `--quiet`: + Do not print progress information to the standard output. Instead, Bundler + will exit using a status code (`$?`). + +* `--retry=[]`: + Retry failed network or git requests for times. + +* `--shebang=`: + Uses the specified ruby executable (usually `ruby`) to execute the scripts + created with `--binstubs`. In addition, if you use `--binstubs` together with + `--shebang jruby` these executables will be changed to execute `jruby` + instead. + + This option is deprecated in favor of the `shebang` setting. + +* `--standalone[=]`: + Makes a bundle that can work without depending on Rubygems or Bundler at + runtime. A space separated list of groups to install has to be specified. + Bundler creates a directory named `bundle` and installs the bundle there. It + also generates a `bundle/bundler/setup.rb` file to replace Bundler's own setup + in the manner required. Using this option implicitly sets `path`, which is a + [remembered option][REMEMBERED OPTIONS]. + +* `--system`: + Installs the gems specified in the bundle to the system's Rubygems location. + This overrides any previous configuration of `--path`. + + This option is deprecated in favor of the `system` setting. + +* `--trust-policy=[]`: + Apply the Rubygems security policy , where policy is one of + `HighSecurity`, `MediumSecurity`, `LowSecurity`, `AlmostNoSecurity`, or + `NoSecurity`. For more details, please see the Rubygems signing documentation + linked below in [SEE ALSO][]. + +* `--with=`: + A space-separated list of groups referencing gems to install. If an + optional group is given it is installed. If a group is given that is + in the remembered list of groups given to --without, it is removed + from that list. + + This option is deprecated in favor of the `with` setting. + +* `--without=`: + A space-separated list of groups referencing gems to skip during installation. + If a group is given that is in the remembered list of groups given + to --with, it is removed from that list. + + This option is deprecated in favor of the `without` setting. + +## DEPLOYMENT MODE + +Bundler's defaults are optimized for development. To switch to +defaults optimized for deployment and for CI, use the `--deployment` +flag. Do not activate deployment mode on development machines, as it +will cause an error when the Gemfile(5) is modified. + +1. A `Gemfile.lock` is required. + + To ensure that the same versions of the gems you developed with + and tested with are also used in deployments, a `Gemfile.lock` + is required. + + This is mainly to ensure that you remember to check your + `Gemfile.lock` into version control. + +2. The `Gemfile.lock` must be up to date + + In development, you can modify your Gemfile(5) and re-run + `bundle install` to [conservatively update][CONSERVATIVE UPDATING] + your `Gemfile.lock` snapshot. + + In deployment, your `Gemfile.lock` should be up-to-date with + changes made in your Gemfile(5). + +3. Gems are installed to `vendor/bundle` not your default system location + + In development, it's convenient to share the gems used in your + application with other applications and other scripts that run on + the system. + + In deployment, isolation is a more important default. In addition, + the user deploying the application may not have permission to install + gems to the system, or the web server may not have permission to + read them. + + As a result, `bundle install --deployment` installs gems to + the `vendor/bundle` directory in the application. This may be + overridden using the `--path` option. + +## SUDO USAGE + +By default, Bundler installs gems to the same location as `gem install`. + +In some cases, that location may not be writable by your Unix user. In +that case, Bundler will stage everything in a temporary directory, +then ask you for your `sudo` password in order to copy the gems into +their system location. + +From your perspective, this is identical to installing the gems +directly into the system. + +You should never use `sudo bundle install`. This is because several +other steps in `bundle install` must be performed as the current user: + +* Updating your `Gemfile.lock` +* Updating your `vendor/cache`, if necessary +* Checking out private git repositories using your user's SSH keys + +Of these three, the first two could theoretically be performed by +`chown`ing the resulting files to `$SUDO_USER`. The third, however, +can only be performed by invoking the `git` command as +the current user. Therefore, git gems are downloaded and installed +into `~/.bundle` rather than $GEM_HOME or $BUNDLE_PATH. + +As a result, you should run `bundle install` as the current user, +and Bundler will ask for your password if it is needed to put the +gems into their final location. + +## INSTALLING GROUPS + +By default, `bundle install` will install all gems in all groups +in your Gemfile(5), except those declared for a different platform. + +However, you can explicitly tell Bundler to skip installing +certain groups with the `--without` option. This option takes +a space-separated list of groups. + +While the `--without` option will skip _installing_ the gems in the +specified groups, it will still _download_ those gems and use them to +resolve the dependencies of every gem in your Gemfile(5). + +This is so that installing a different set of groups on another + machine (such as a production server) will not change the +gems and versions that you have already developed and tested against. + +`Bundler offers a rock-solid guarantee that the third-party +code you are running in development and testing is also the +third-party code you are running in production. You can choose +to exclude some of that code in different environments, but you +will never be caught flat-footed by different versions of +third-party code being used in different environments.` + +For a simple illustration, consider the following Gemfile(5): + + source 'https://rubygems.org' + + gem 'sinatra' + + group :production do + gem 'rack-perftools-profiler' + end + +In this case, `sinatra` depends on any version of Rack (`>= 1.0`), while +`rack-perftools-profiler` depends on 1.x (`~> 1.0`). + +When you run `bundle install --without production` in development, we +look at the dependencies of `rack-perftools-profiler` as well. That way, +you do not spend all your time developing against Rack 2.0, using new +APIs unavailable in Rack 1.x, only to have Bundler switch to Rack 1.2 +when the `production` group _is_ used. + +This should not cause any problems in practice, because we do not +attempt to `install` the gems in the excluded groups, and only evaluate +as part of the dependency resolution process. + +This also means that you cannot include different versions of the same +gem in different groups, because doing so would result in different +sets of dependencies used in development and production. Because of +the vagaries of the dependency resolution process, this usually +affects more than the gems you list in your Gemfile(5), and can +(surprisingly) radically change the gems you are using. + +## THE GEMFILE.LOCK + +When you run `bundle install`, Bundler will persist the full names +and versions of all gems that you used (including dependencies of +the gems specified in the Gemfile(5)) into a file called `Gemfile.lock`. + +Bundler uses this file in all subsequent calls to `bundle install`, +which guarantees that you always use the same exact code, even +as your application moves across machines. + +Because of the way dependency resolution works, even a +seemingly small change (for instance, an update to a point-release +of a dependency of a gem in your Gemfile(5)) can result in radically +different gems being needed to satisfy all dependencies. + +As a result, you `SHOULD` check your `Gemfile.lock` into version +control, in both applications and gems. If you do not, every machine that +checks out your repository (including your production server) will resolve all +dependencies again, which will result in different versions of +third-party code being used if `any` of the gems in the Gemfile(5) +or any of their dependencies have been updated. + +When Bundler first shipped, the `Gemfile.lock` was included in the `.gitignore` +file included with generated gems. Over time, however, it became clear that +this practice forces the pain of broken dependencies onto new contributors, +while leaving existing contributors potentially unaware of the problem. Since +`bundle install` is usually the first step towards a contribution, the pain of +broken dependencies would discourage new contributors from contributing. As a +result, we have revised our guidance for gem authors to now recommend checking +in the lock for gems. + +## CONSERVATIVE UPDATING + +When you make a change to the Gemfile(5) and then run `bundle install`, +Bundler will update only the gems that you modified. + +In other words, if a gem that you `did not modify` worked before +you called `bundle install`, it will continue to use the exact +same versions of all dependencies as it used before the update. + +Let's take a look at an example. Here's your original Gemfile(5): + + source 'https://rubygems.org' + + gem 'actionpack', '2.3.8' + gem 'activemerchant' + +In this case, both `actionpack` and `activemerchant` depend on +`activesupport`. The `actionpack` gem depends on `activesupport 2.3.8` +and `rack ~> 1.1.0`, while the `activemerchant` gem depends on +`activesupport >= 2.3.2`, `braintree >= 2.0.0`, and `builder >= 2.0.0`. + +When the dependencies are first resolved, Bundler will select +`activesupport 2.3.8`, which satisfies the requirements of both +gems in your Gemfile(5). + +Next, you modify your Gemfile(5) to: + + source 'https://rubygems.org' + + gem 'actionpack', '3.0.0.rc' + gem 'activemerchant' + +The `actionpack 3.0.0.rc` gem has a number of new dependencies, +and updates the `activesupport` dependency to `= 3.0.0.rc` and +the `rack` dependency to `~> 1.2.1`. + +When you run `bundle install`, Bundler notices that you changed +the `actionpack` gem, but not the `activemerchant` gem. It +evaluates the gems currently being used to satisfy its requirements: + + * `activesupport 2.3.8`: + also used to satisfy a dependency in `activemerchant`, + which is not being updated + * `rack ~> 1.1.0`: + not currently being used to satisfy another dependency + +Because you did not explicitly ask to update `activemerchant`, +you would not expect it to suddenly stop working after updating +`actionpack`. However, satisfying the new `activesupport 3.0.0.rc` +dependency of actionpack requires updating one of its dependencies. + +Even though `activemerchant` declares a very loose dependency +that theoretically matches `activesupport 3.0.0.rc`, Bundler treats +gems in your Gemfile(5) that have not changed as an atomic unit +together with their dependencies. In this case, the `activemerchant` +dependency is treated as `activemerchant 1.7.1 + activesupport 2.3.8`, +so `bundle install` will report that it cannot update `actionpack`. + +To explicitly update `actionpack`, including its dependencies +which other gems in the Gemfile(5) still depend on, run +`bundle update actionpack` (see `bundle update(1)`). + +`Summary`: In general, after making a change to the Gemfile(5) , you +should first try to run `bundle install`, which will guarantee that no +other gem in the Gemfile(5) is impacted by the change. If that +does not work, run [bundle update(1)](bundle-update.1.html). + +## SEE ALSO + +* [Gem install docs](http://guides.rubygems.org/rubygems-basics/#installing-gems) +* [Rubygems signing docs](http://guides.rubygems.org/security/) diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-list.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-list.1 new file mode 100644 index 0000000..d82093a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-list.1 @@ -0,0 +1,50 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-LIST" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-list\fR \- List all the gems in the bundle +. +.SH "SYNOPSIS" +\fBbundle list\fR [\-\-name\-only] [\-\-paths] [\-\-without\-group=GROUP[ GROUP\.\.\.]] [\-\-only\-group=GROUP[ GROUP\.\.\.]] +. +.SH "DESCRIPTION" +Prints a list of all the gems in the bundle including their version\. +. +.P +Example: +. +.P +bundle list \-\-name\-only +. +.P +bundle list \-\-paths +. +.P +bundle list \-\-without\-group test +. +.P +bundle list \-\-only\-group dev +. +.P +bundle list \-\-only\-group dev test \-\-paths +. +.SH "OPTIONS" +. +.TP +\fB\-\-name\-only\fR +Print only the name of each gem\. +. +.TP +\fB\-\-paths\fR +Print the path to each gem in the bundle\. +. +.TP +\fB\-\-without\-group=\fR +A space\-separated list of groups of gems to skip during printing\. +. +.TP +\fB\-\-only\-group=\fR +A space\-separated list of groups of gems to print\. + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-list.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-list.1.ronn new file mode 100644 index 0000000..dc058ec --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-list.1.ronn @@ -0,0 +1,33 @@ +bundle-list(1) -- List all the gems in the bundle +========================================================================= + +## SYNOPSIS + +`bundle list` [--name-only] [--paths] [--without-group=GROUP[ GROUP...]] [--only-group=GROUP[ GROUP...]] + +## DESCRIPTION + +Prints a list of all the gems in the bundle including their version. + +Example: + +bundle list --name-only + +bundle list --paths + +bundle list --without-group test + +bundle list --only-group dev + +bundle list --only-group dev test --paths + +## OPTIONS + +* `--name-only`: + Print only the name of each gem. +* `--paths`: + Print the path to each gem in the bundle. +* `--without-group=`: + A space-separated list of groups of gems to skip during printing. +* `--only-group=`: + A space-separated list of groups of gems to print. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-lock.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-lock.1 new file mode 100644 index 0000000..65586c8 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-lock.1 @@ -0,0 +1,84 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-LOCK" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing +. +.SH "SYNOPSIS" +\fBbundle lock\fR [\-\-update] [\-\-local] [\-\-print] [\-\-lockfile=PATH] [\-\-full\-index] [\-\-add\-platform] [\-\-remove\-platform] [\-\-patch] [\-\-minor] [\-\-major] [\-\-strict] [\-\-conservative] +. +.SH "DESCRIPTION" +Lock the gems specified in Gemfile\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-update=<*gems>\fR +Ignores the existing lockfile\. Resolve then updates lockfile\. Taking a list of gems or updating all gems if no list is given\. +. +.TP +\fB\-\-local\fR +Do not attempt to connect to \fBrubygems\.org\fR\. Instead, Bundler will use the gems already present in Rubygems\' cache or in \fBvendor/cache\fR\. Note that if a appropriate platform\-specific gem exists on \fBrubygems\.org\fR it will not be found\. +. +.TP +\fB\-\-print\fR +Prints the lockfile to STDOUT instead of writing to the file system\. +. +.TP +\fB\-\-lockfile=\fR +The path where the lockfile should be written to\. +. +.TP +\fB\-\-full\-index\fR +Fall back to using the single\-file index of all gems\. +. +.TP +\fB\-\-add\-platform\fR +Add a new platform to the lockfile, re\-resolving for the addition of that platform\. +. +.TP +\fB\-\-remove\-platform\fR +Remove a platform from the lockfile\. +. +.TP +\fB\-\-patch\fR +If updating, prefer updating only to next patch version\. +. +.TP +\fB\-\-minor\fR +If updating, prefer updating only to next minor version\. +. +.TP +\fB\-\-major\fR +If updating, prefer updating to next major version (default)\. +. +.TP +\fB\-\-strict\fR +If updating, do not allow any gem to be updated past latest \-\-patch | \-\-minor | \-\-major\. +. +.TP +\fB\-\-conservative\fR +If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated\. +. +.SH "UPDATING ALL GEMS" +If you run \fBbundle lock\fR with \fB\-\-update\fR option without list of gems, bundler will ignore any previously installed gems and resolve all dependencies again based on the latest versions of all gems available in the sources\. +. +.SH "UPDATING A LIST OF GEMS" +Sometimes, you want to update a single gem in the Gemfile(5), and leave the rest of the gems that you specified locked to the versions in the \fBGemfile\.lock\fR\. +. +.P +For instance, you only want to update \fBnokogiri\fR, run \fBbundle lock \-\-update nokogiri\fR\. +. +.P +Bundler will update \fBnokogiri\fR and any of its dependencies, but leave the rest of the gems that you specified locked to the versions in the \fBGemfile\.lock\fR\. +. +.SH "SUPPORTING OTHER PLATFORMS" +If you want your bundle to support platforms other than the one you\'re running locally, you can run \fBbundle lock \-\-add\-platform PLATFORM\fR to add PLATFORM to the lockfile, force bundler to re\-resolve and consider the new platform when picking gems, all without needing to have a machine that matches PLATFORM handy to install those platform\-specific gems on\. +. +.P +For a full explanation of gem platforms, see \fBgem help platform\fR\. +. +.SH "PATCH LEVEL OPTIONS" +See bundle update(1) \fIbundle\-update\.1\.html\fR for details\. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-lock.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-lock.1.ronn new file mode 100644 index 0000000..3aa5920 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-lock.1.ronn @@ -0,0 +1,94 @@ +bundle-lock(1) -- Creates / Updates a lockfile without installing +================================================================= + +## SYNOPSIS + +`bundle lock` [--update] + [--local] + [--print] + [--lockfile=PATH] + [--full-index] + [--add-platform] + [--remove-platform] + [--patch] + [--minor] + [--major] + [--strict] + [--conservative] + +## DESCRIPTION + +Lock the gems specified in Gemfile. + +## OPTIONS + +* `--update=<*gems>`: + Ignores the existing lockfile. Resolve then updates lockfile. Taking a list + of gems or updating all gems if no list is given. + +* `--local`: + Do not attempt to connect to `rubygems.org`. Instead, Bundler will use the + gems already present in Rubygems' cache or in `vendor/cache`. Note that if a + appropriate platform-specific gem exists on `rubygems.org` it will not be + found. + +* `--print`: + Prints the lockfile to STDOUT instead of writing to the file system. + +* `--lockfile=`: + The path where the lockfile should be written to. + +* `--full-index`: + Fall back to using the single-file index of all gems. + +* `--add-platform`: + Add a new platform to the lockfile, re-resolving for the addition of that + platform. + +* `--remove-platform`: + Remove a platform from the lockfile. + +* `--patch`: + If updating, prefer updating only to next patch version. + +* `--minor`: + If updating, prefer updating only to next minor version. + +* `--major`: + If updating, prefer updating to next major version (default). + +* `--strict`: + If updating, do not allow any gem to be updated past latest --patch | --minor | --major. + +* `--conservative`: + If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated. + +## UPDATING ALL GEMS + +If you run `bundle lock` with `--update` option without list of gems, bundler will +ignore any previously installed gems and resolve all dependencies again based +on the latest versions of all gems available in the sources. + +## UPDATING A LIST OF GEMS + +Sometimes, you want to update a single gem in the Gemfile(5), and leave the rest of +the gems that you specified locked to the versions in the `Gemfile.lock`. + +For instance, you only want to update `nokogiri`, run `bundle lock --update nokogiri`. + +Bundler will update `nokogiri` and any of its dependencies, but leave the rest of the +gems that you specified locked to the versions in the `Gemfile.lock`. + +## SUPPORTING OTHER PLATFORMS + +If you want your bundle to support platforms other than the one you're running +locally, you can run `bundle lock --add-platform PLATFORM` to add PLATFORM to +the lockfile, force bundler to re-resolve and consider the new platform when +picking gems, all without needing to have a machine that matches PLATFORM handy +to install those platform-specific gems on. + +For a full explanation of gem platforms, see `gem help platform`. + +## PATCH LEVEL OPTIONS + +See [bundle update(1)](bundle-update.1.html) for details. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-open.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-open.1 new file mode 100644 index 0000000..b2327fa --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-open.1 @@ -0,0 +1,32 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-OPEN" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle +. +.SH "SYNOPSIS" +\fBbundle open\fR [GEM] +. +.SH "DESCRIPTION" +Opens the source directory of the provided GEM in your editor\. +. +.P +For this to work the \fBEDITOR\fR or \fBBUNDLER_EDITOR\fR environment variable has to be set\. +. +.P +Example: +. +.IP "" 4 +. +.nf + +bundle open \'rack\' +. +.fi +. +.IP "" 0 +. +.P +Will open the source directory for the \'rack\' gem in your bundle\. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-open.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-open.1.ronn new file mode 100644 index 0000000..497beac --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-open.1.ronn @@ -0,0 +1,19 @@ +bundle-open(1) -- Opens the source directory for a gem in your bundle +===================================================================== + +## SYNOPSIS + +`bundle open` [GEM] + +## DESCRIPTION + +Opens the source directory of the provided GEM in your editor. + +For this to work the `EDITOR` or `BUNDLER_EDITOR` environment variable has to +be set. + +Example: + + bundle open 'rack' + +Will open the source directory for the 'rack' gem in your bundle. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-outdated.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-outdated.1 new file mode 100644 index 0000000..8961552 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-outdated.1 @@ -0,0 +1,148 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-OUTDATED" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-outdated\fR \- List installed gems with newer versions available +. +.SH "SYNOPSIS" +\fBbundle outdated\fR [GEM] [\-\-local] [\-\-pre] [\-\-source] [\-\-strict] [\-\-parseable | \-\-porcelain] [\-\-group=GROUP] [\-\-groups] [\-\-patch|\-\-minor|\-\-major] [\-\-filter\-major] [\-\-filter\-minor] [\-\-filter\-patch] [\-\-only\-explicit] +. +.SH "DESCRIPTION" +Outdated lists the names and versions of gems that have a newer version available in the given source\. Calling outdated with [GEM [GEM]] will only check for newer versions of the given gems\. Prerelease gems are ignored by default\. If your gems are up to date, Bundler will exit with a status of 0\. Otherwise, it will exit 1\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-local\fR +Do not attempt to fetch gems remotely and use the gem cache instead\. +. +.TP +\fB\-\-pre\fR +Check for newer pre\-release gems\. +. +.TP +\fB\-\-source\fR +Check against a specific source\. +. +.TP +\fB\-\-strict\fR +Only list newer versions allowed by your Gemfile requirements, also respecting conservative update flags (\-\-patch, \-\-minor, \-\-major)\. +. +.TP +\fB\-\-parseable\fR, \fB\-\-porcelain\fR +Use minimal formatting for more parseable output\. +. +.TP +\fB\-\-group\fR +List gems from a specific group\. +. +.TP +\fB\-\-groups\fR +List gems organized by groups\. +. +.TP +\fB\-\-minor\fR +Prefer updating only to next minor version\. +. +.TP +\fB\-\-major\fR +Prefer updating to next major version (default)\. +. +.TP +\fB\-\-patch\fR +Prefer updating only to next patch version\. +. +.TP +\fB\-\-filter\-major\fR +Only list major newer versions\. +. +.TP +\fB\-\-filter\-minor\fR +Only list minor newer versions\. +. +.TP +\fB\-\-filter\-patch\fR +Only list patch newer versions\. +. +.TP +\fB\-\-only\-explicit\fR +Only list gems specified in your Gemfile, not their dependencies\. +. +.SH "PATCH LEVEL OPTIONS" +See bundle update(1) \fIbundle\-update\.1\.html\fR for details\. +. +.SH "FILTERING OUTPUT" +The 3 filtering options do not affect the resolution of versions, merely what versions are shown in the output\. +. +.P +If the regular output shows the following: +. +.IP "" 4 +. +.nf + +* faker (newest 1\.6\.6, installed 1\.6\.5, requested ~> 1\.4) in groups "development, test" +* hashie (newest 3\.4\.6, installed 1\.2\.0, requested = 1\.2\.0) in groups "default" +* headless (newest 2\.3\.1, installed 2\.2\.3) in groups "test" +. +.fi +. +.IP "" 0 +. +.P +\fB\-\-filter\-major\fR would only show: +. +.IP "" 4 +. +.nf + +* hashie (newest 3\.4\.6, installed 1\.2\.0, requested = 1\.2\.0) in groups "default" +. +.fi +. +.IP "" 0 +. +.P +\fB\-\-filter\-minor\fR would only show: +. +.IP "" 4 +. +.nf + +* headless (newest 2\.3\.1, installed 2\.2\.3) in groups "test" +. +.fi +. +.IP "" 0 +. +.P +\fB\-\-filter\-patch\fR would only show: +. +.IP "" 4 +. +.nf + +* faker (newest 1\.6\.6, installed 1\.6\.5, requested ~> 1\.4) in groups "development, test" +. +.fi +. +.IP "" 0 +. +.P +Filter options can be combined\. \fB\-\-filter\-minor\fR and \fB\-\-filter\-patch\fR would show: +. +.IP "" 4 +. +.nf + +* faker (newest 1\.6\.6, installed 1\.6\.5, requested ~> 1\.4) in groups "development, test" +* headless (newest 2\.3\.1, installed 2\.2\.3) in groups "test" +. +.fi +. +.IP "" 0 +. +.P +Combining all three \fBfilter\fR options would be the same result as providing none of them\. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-outdated.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-outdated.1.ronn new file mode 100644 index 0000000..04096ff --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-outdated.1.ronn @@ -0,0 +1,102 @@ +bundle-outdated(1) -- List installed gems with newer versions available +======================================================================= + +## SYNOPSIS + +`bundle outdated` [GEM] [--local] + [--pre] + [--source] + [--strict] + [--parseable | --porcelain] + [--group=GROUP] + [--groups] + [--patch|--minor|--major] + [--filter-major] + [--filter-minor] + [--filter-patch] + [--only-explicit] + +## DESCRIPTION + +Outdated lists the names and versions of gems that have a newer version available +in the given source. Calling outdated with [GEM [GEM]] will only check for newer +versions of the given gems. Prerelease gems are ignored by default. If your gems +are up to date, Bundler will exit with a status of 0. Otherwise, it will exit 1. + +## OPTIONS + +* `--local`: + Do not attempt to fetch gems remotely and use the gem cache instead. + +* `--pre`: + Check for newer pre-release gems. + +* `--source`: + Check against a specific source. + +* `--strict`: + Only list newer versions allowed by your Gemfile requirements, also respecting conservative update flags (--patch, --minor, --major). + +* `--parseable`, `--porcelain`: + Use minimal formatting for more parseable output. + +* `--group`: + List gems from a specific group. + +* `--groups`: + List gems organized by groups. + +* `--minor`: + Prefer updating only to next minor version. + +* `--major`: + Prefer updating to next major version (default). + +* `--patch`: + Prefer updating only to next patch version. + +* `--filter-major`: + Only list major newer versions. + +* `--filter-minor`: + Only list minor newer versions. + +* `--filter-patch`: + Only list patch newer versions. + +* `--only-explicit`: + Only list gems specified in your Gemfile, not their dependencies. + +## PATCH LEVEL OPTIONS + +See [bundle update(1)](bundle-update.1.html) for details. + +## FILTERING OUTPUT + +The 3 filtering options do not affect the resolution of versions, merely what versions are shown +in the output. + +If the regular output shows the following: + + * faker (newest 1.6.6, installed 1.6.5, requested ~> 1.4) in groups "development, test" + * hashie (newest 3.4.6, installed 1.2.0, requested = 1.2.0) in groups "default" + * headless (newest 2.3.1, installed 2.2.3) in groups "test" + +`--filter-major` would only show: + + * hashie (newest 3.4.6, installed 1.2.0, requested = 1.2.0) in groups "default" + +`--filter-minor` would only show: + + * headless (newest 2.3.1, installed 2.2.3) in groups "test" + +`--filter-patch` would only show: + + * faker (newest 1.6.6, installed 1.6.5, requested ~> 1.4) in groups "development, test" + +Filter options can be combined. `--filter-minor` and `--filter-patch` would show: + + * faker (newest 1.6.6, installed 1.6.5, requested ~> 1.4) in groups "development, test" + * headless (newest 2.3.1, installed 2.2.3) in groups "test" + +Combining all three `filter` options would be the same result as providing none of them. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-platform.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-platform.1 new file mode 100644 index 0000000..2d24507 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-platform.1 @@ -0,0 +1,71 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-PLATFORM" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-platform\fR \- Displays platform compatibility information +. +.SH "SYNOPSIS" +\fBbundle platform\fR [\-\-ruby] +. +.SH "DESCRIPTION" +\fBplatform\fR displays information from your Gemfile, Gemfile\.lock, and Ruby VM about your platform\. +. +.P +For instance, using this Gemfile(5): +. +.IP "" 4 +. +.nf + +source "https://rubygems\.org" + +ruby "3\.1\.2" + +gem "rack" +. +.fi +. +.IP "" 0 +. +.P +If you run \fBbundle platform\fR on Ruby 3\.1\.2, it displays the following output: +. +.IP "" 4 +. +.nf + +Your platform is: x86_64\-linux + +Your app has gems that work on these platforms: +* arm64\-darwin\-21 +* ruby +* x64\-mingw\-ucrt +* x86_64\-linux + +Your Gemfile specifies a Ruby version requirement: +* ruby 3\.1\.2 + +Your current platform satisfies the Ruby version requirement\. +. +.fi +. +.IP "" 0 +. +.P +\fBplatform\fR lists all the platforms in your \fBGemfile\.lock\fR as well as the \fBruby\fR directive if applicable from your Gemfile(5)\. It also lets you know if the \fBruby\fR directive requirement has been met\. If \fBruby\fR directive doesn\'t match the running Ruby VM, it tells you what part does not\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-ruby\fR +It will display the ruby directive information, so you don\'t have to parse it from the Gemfile(5)\. +. +.SH "SEE ALSO" +. +.IP "\(bu" 4 +bundle\-lock(1) \fIbundle\-lock\.1\.ronn\fR +. +.IP "" 0 + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-platform.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-platform.1.ronn new file mode 100644 index 0000000..eb9baa1 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-platform.1.ronn @@ -0,0 +1,49 @@ +bundle-platform(1) -- Displays platform compatibility information +================================================================= + +## SYNOPSIS + +`bundle platform` [--ruby] + +## DESCRIPTION + +`platform` displays information from your Gemfile, Gemfile.lock, and Ruby +VM about your platform. + +For instance, using this Gemfile(5): + + source "https://rubygems.org" + + ruby "3.1.2" + + gem "rack" + +If you run `bundle platform` on Ruby 3.1.2, it displays the following output: + + Your platform is: x86_64-linux + + Your app has gems that work on these platforms: + * arm64-darwin-21 + * ruby + * x64-mingw-ucrt + * x86_64-linux + + Your Gemfile specifies a Ruby version requirement: + * ruby 3.1.2 + + Your current platform satisfies the Ruby version requirement. + +`platform` lists all the platforms in your `Gemfile.lock` as well as the +`ruby` directive if applicable from your Gemfile(5). It also lets you know +if the `ruby` directive requirement has been met. If `ruby` directive doesn't +match the running Ruby VM, it tells you what part does not. + +## OPTIONS + +* `--ruby`: + It will display the ruby directive information, so you don't have to + parse it from the Gemfile(5). + +## SEE ALSO + +* [bundle-lock(1)](bundle-lock.1.ronn) diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-plugin.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-plugin.1 new file mode 100644 index 0000000..3a08bf8 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-plugin.1 @@ -0,0 +1,81 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-PLUGIN" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-plugin\fR \- Manage Bundler plugins +. +.SH "SYNOPSIS" +\fBbundle plugin\fR install PLUGINS [\-\-source=\fISOURCE\fR] [\-\-version=\fIversion\fR] [\-\-git|\-\-local_git=\fIgit\-url\fR] [\-\-branch=\fIbranch\fR|\-\-ref=\fIrev\fR] +. +.br +\fBbundle plugin\fR uninstall PLUGINS +. +.br +\fBbundle plugin\fR list +. +.br +\fBbundle plugin\fR help [COMMAND] +. +.SH "DESCRIPTION" +You can install, uninstall, and list plugin(s) with this command to extend functionalities of Bundler\. +. +.SH "SUB\-COMMANDS" +. +.SS "install" +Install the given plugin(s)\. +. +.IP "\(bu" 4 +\fBbundle plugin install bundler\-graph\fR: Install bundler\-graph gem from RubyGems\.org\. The global source, specified in source in Gemfile is ignored\. +. +.IP "\(bu" 4 +\fBbundle plugin install bundler\-graph \-\-source https://example\.com\fR: Install bundler\-graph gem from example\.com\. The global source, specified in source in Gemfile is not considered\. +. +.IP "\(bu" 4 +\fBbundle plugin install bundler\-graph \-\-version 0\.2\.1\fR: You can specify the version of the gem via \fB\-\-version\fR\. +. +.IP "\(bu" 4 +\fBbundle plugin install bundler\-graph \-\-git https://github\.com/rubygems/bundler\-graph\fR: Install bundler\-graph gem from Git repository\. \fB\-\-git\fR can be replaced with \fB\-\-local\-git\fR\. You cannot use both \fB\-\-git\fR and \fB\-\-local\-git\fR\. You can use standard Git URLs like: +. +.IP "\(bu" 4 +\fBssh://[user@]host\.xz[:port]/path/to/repo\.git\fR +. +.IP "\(bu" 4 +\fBhttp[s]://host\.xz[:port]/path/to/repo\.git\fR +. +.IP "\(bu" 4 +\fB/path/to/repo\fR +. +.IP "\(bu" 4 +\fBfile:///path/to/repo\fR +. +.IP "" 0 +. +.IP +When you specify \fB\-\-git\fR/\fB\-\-local\-git\fR, you can use \fB\-\-branch\fR or \fB\-\-ref\fR to specify any branch, tag, or commit hash (revision) to use\. When you specify both, only the latter is used\. +. +.IP "" 0 +. +.SS "uninstall" +Uninstall the plugin(s) specified in PLUGINS\. +. +.SS "list" +List the installed plugins and available commands\. +. +.P +No options\. +. +.SS "help" +Describe subcommands or one specific subcommand\. +. +.P +No options\. +. +.SH "SEE ALSO" +. +.IP "\(bu" 4 +How to write a Bundler plugin \fIhttps://bundler\.io/guides/bundler_plugins\.html\fR +. +.IP "" 0 + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-plugin.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-plugin.1.ronn new file mode 100644 index 0000000..4f234ee --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-plugin.1.ronn @@ -0,0 +1,59 @@ +bundle-plugin(1) -- Manage Bundler plugins +========================================== + +## SYNOPSIS + +`bundle plugin` install PLUGINS [--source=] [--version=] + [--git|--local_git=] [--branch=|--ref=]
    +`bundle plugin` uninstall PLUGINS
    +`bundle plugin` list
    +`bundle plugin` help [COMMAND] + +## DESCRIPTION + +You can install, uninstall, and list plugin(s) with this command to extend functionalities of Bundler. + +## SUB-COMMANDS + +### install + +Install the given plugin(s). + +* `bundle plugin install bundler-graph`: + Install bundler-graph gem from RubyGems.org. The global source, specified in source in Gemfile is ignored. + +* `bundle plugin install bundler-graph --source https://example.com`: + Install bundler-graph gem from example.com. The global source, specified in source in Gemfile is not considered. + +* `bundle plugin install bundler-graph --version 0.2.1`: + You can specify the version of the gem via `--version`. + +* `bundle plugin install bundler-graph --git https://github.com/rubygems/bundler-graph`: + Install bundler-graph gem from Git repository. `--git` can be replaced with `--local-git`. You cannot use both `--git` and `--local-git`. You can use standard Git URLs like: + + * `ssh://[user@]host.xz[:port]/path/to/repo.git` + * `http[s]://host.xz[:port]/path/to/repo.git` + * `/path/to/repo` + * `file:///path/to/repo` + + When you specify `--git`/`--local-git`, you can use `--branch` or `--ref` to specify any branch, tag, or commit hash (revision) to use. When you specify both, only the latter is used. + +### uninstall + +Uninstall the plugin(s) specified in PLUGINS. + +### list + +List the installed plugins and available commands. + +No options. + +### help + +Describe subcommands or one specific subcommand. + +No options. + +## SEE ALSO + +* [How to write a Bundler plugin](https://bundler.io/guides/bundler_plugins.html) diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-pristine.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-pristine.1 new file mode 100644 index 0000000..5f562a2 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-pristine.1 @@ -0,0 +1,34 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-PRISTINE" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition +. +.SH "SYNOPSIS" +\fBbundle pristine\fR +. +.SH "DESCRIPTION" +\fBpristine\fR restores the installed gems in the bundle to their pristine condition using the local gem cache from RubyGems\. For git gems, a forced checkout will be performed\. +. +.P +For further explanation, \fBbundle pristine\fR ignores unpacked files on disk\. In other words, this command utilizes the local \fB\.gem\fR cache or the gem\'s git repository as if one were installing from scratch\. +. +.P +Note: the Bundler gem cannot be restored to its original state with \fBpristine\fR\. One also cannot use \fBbundle pristine\fR on gems with a \'path\' option in the Gemfile, because bundler has no original copy it can restore from\. +. +.P +When is it practical to use \fBbundle pristine\fR? +. +.P +It comes in handy when a developer is debugging a gem\. \fBbundle pristine\fR is a great way to get rid of experimental changes to a gem that one may not want\. +. +.P +Why use \fBbundle pristine\fR over \fBgem pristine \-\-all\fR? +. +.P +Both commands are very similar\. For context: \fBbundle pristine\fR, without arguments, cleans all gems from the lockfile\. Meanwhile, \fBgem pristine \-\-all\fR cleans all installed gems for that Ruby version\. +. +.P +If a developer forgets which gems in their project they might have been debugging, the Rubygems \fBgem pristine [GEMNAME]\fR command may be inconvenient\. One can avoid waiting for \fBgem pristine \-\-all\fR, and instead run \fBbundle pristine\fR\. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-pristine.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-pristine.1.ronn new file mode 100644 index 0000000..e2d6b6a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-pristine.1.ronn @@ -0,0 +1,34 @@ +bundle-pristine(1) -- Restores installed gems to their pristine condition +=========================================================================== + +## SYNOPSIS + +`bundle pristine` + +## DESCRIPTION + +`pristine` restores the installed gems in the bundle to their pristine condition +using the local gem cache from RubyGems. For git gems, a forced checkout will be performed. + +For further explanation, `bundle pristine` ignores unpacked files on disk. In other +words, this command utilizes the local `.gem` cache or the gem's git repository +as if one were installing from scratch. + +Note: the Bundler gem cannot be restored to its original state with `pristine`. +One also cannot use `bundle pristine` on gems with a 'path' option in the Gemfile, +because bundler has no original copy it can restore from. + +When is it practical to use `bundle pristine`? + +It comes in handy when a developer is debugging a gem. `bundle pristine` is a +great way to get rid of experimental changes to a gem that one may not want. + +Why use `bundle pristine` over `gem pristine --all`? + +Both commands are very similar. +For context: `bundle pristine`, without arguments, cleans all gems from the lockfile. +Meanwhile, `gem pristine --all` cleans all installed gems for that Ruby version. + +If a developer forgets which gems in their project they might +have been debugging, the Rubygems `gem pristine [GEMNAME]` command may be inconvenient. +One can avoid waiting for `gem pristine --all`, and instead run `bundle pristine`. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-remove.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-remove.1 new file mode 100644 index 0000000..128ac64 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-remove.1 @@ -0,0 +1,31 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-REMOVE" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-remove\fR \- Removes gems from the Gemfile +. +.SH "SYNOPSIS" +\fBbundle remove [GEM [GEM \.\.\.]] [\-\-install]\fR +. +.SH "DESCRIPTION" +Removes the given gems from the Gemfile while ensuring that the resulting Gemfile is still valid\. If a gem cannot be removed, a warning is printed\. If a gem is already absent from the Gemfile, and error is raised\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-install\fR +Runs \fBbundle install\fR after the given gems have been removed from the Gemfile, which ensures that both the lockfile and the installed gems on disk are also updated to remove the given gem(s)\. +. +.P +Example: +. +.P +bundle remove rails +. +.P +bundle remove rails rack +. +.P +bundle remove rails rack \-\-install diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-remove.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-remove.1.ronn new file mode 100644 index 0000000..40a239b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-remove.1.ronn @@ -0,0 +1,23 @@ +bundle-remove(1) -- Removes gems from the Gemfile +=========================================================================== + +## SYNOPSIS + +`bundle remove [GEM [GEM ...]] [--install]` + +## DESCRIPTION + +Removes the given gems from the Gemfile while ensuring that the resulting Gemfile is still valid. If a gem cannot be removed, a warning is printed. If a gem is already absent from the Gemfile, and error is raised. + +## OPTIONS + +* `--install`: + Runs `bundle install` after the given gems have been removed from the Gemfile, which ensures that both the lockfile and the installed gems on disk are also updated to remove the given gem(s). + +Example: + +bundle remove rails + +bundle remove rails rack + +bundle remove rails rack --install diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-show.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-show.1 new file mode 100644 index 0000000..1d747fd --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-show.1 @@ -0,0 +1,23 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-SHOW" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem +. +.SH "SYNOPSIS" +\fBbundle show\fR [GEM] [\-\-paths] +. +.SH "DESCRIPTION" +Without the [GEM] option, \fBshow\fR will print a list of the names and versions of all gems that are required by your [\fBGemfile(5)\fR][Gemfile(5)], sorted by name\. +. +.P +Calling show with [GEM] will list the exact location of that gem on your machine\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-paths\fR +List the paths of all gems that are required by your [\fBGemfile(5)\fR][Gemfile(5)], sorted by gem name\. + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-show.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-show.1.ronn new file mode 100644 index 0000000..a6a59a1 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-show.1.ronn @@ -0,0 +1,21 @@ +bundle-show(1) -- Shows all the gems in your bundle, or the path to a gem +========================================================================= + +## SYNOPSIS + +`bundle show` [GEM] + [--paths] + +## DESCRIPTION + +Without the [GEM] option, `show` will print a list of the names and versions of +all gems that are required by your [`Gemfile(5)`][Gemfile(5)], sorted by name. + +Calling show with [GEM] will list the exact location of that gem on your +machine. + +## OPTIONS + +* `--paths`: + List the paths of all gems that are required by your [`Gemfile(5)`][Gemfile(5)], + sorted by gem name. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-update.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-update.1 new file mode 100644 index 0000000..15e0517 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-update.1 @@ -0,0 +1,394 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-UPDATE" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-update\fR \- Update your gems to the latest available versions +. +.SH "SYNOPSIS" +\fBbundle update\fR \fI*gems\fR [\-\-all] [\-\-group=NAME] [\-\-source=NAME] [\-\-local] [\-\-ruby] [\-\-bundler[=VERSION]] [\-\-full\-index] [\-\-jobs=JOBS] [\-\-quiet] [\-\-patch|\-\-minor|\-\-major] [\-\-redownload] [\-\-strict] [\-\-conservative] +. +.SH "DESCRIPTION" +Update the gems specified (all gems, if \fB\-\-all\fR flag is used), ignoring the previously installed gems specified in the \fBGemfile\.lock\fR\. In general, you should use bundle install(1) \fIbundle\-install\.1\.html\fR to install the same exact gems and versions across machines\. +. +.P +You would use \fBbundle update\fR to explicitly update the version of a gem\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-all\fR +Update all gems specified in Gemfile\. +. +.TP +\fB\-\-group=\fR, \fB\-g=[]\fR +Only update the gems in the specified group\. For instance, you can update all gems in the development group with \fBbundle update \-\-group development\fR\. You can also call \fBbundle update rails \-\-group test\fR to update the rails gem and all gems in the test group, for example\. +. +.TP +\fB\-\-source=\fR +The name of a \fB:git\fR or \fB:path\fR source used in the Gemfile(5)\. For instance, with a \fB:git\fR source of \fBhttp://github\.com/rails/rails\.git\fR, you would call \fBbundle update \-\-source rails\fR +. +.TP +\fB\-\-local\fR +Do not attempt to fetch gems remotely and use the gem cache instead\. +. +.TP +\fB\-\-ruby\fR +Update the locked version of Ruby to the current version of Ruby\. +. +.TP +\fB\-\-bundler\fR +Update the locked version of bundler to the invoked bundler version\. +. +.TP +\fB\-\-full\-index\fR +Fall back to using the single\-file index of all gems\. +. +.TP +\fB\-\-jobs=[]\fR, \fB\-j[]\fR +Specify the number of jobs to run in parallel\. The default is the number of available processors\. +. +.TP +\fB\-\-retry=[]\fR +Retry failed network or git requests for \fInumber\fR times\. +. +.TP +\fB\-\-quiet\fR +Only output warnings and errors\. +. +.TP +\fB\-\-redownload\fR +Force downloading every gem\. +. +.TP +\fB\-\-patch\fR +Prefer updating only to next patch version\. +. +.TP +\fB\-\-minor\fR +Prefer updating only to next minor version\. +. +.TP +\fB\-\-major\fR +Prefer updating to next major version (default)\. +. +.TP +\fB\-\-strict\fR +Do not allow any gem to be updated past latest \fB\-\-patch\fR | \fB\-\-minor\fR | \fB\-\-major\fR\. +. +.TP +\fB\-\-conservative\fR +Use bundle install conservative update behavior and do not allow indirect dependencies to be updated\. +. +.SH "UPDATING ALL GEMS" +If you run \fBbundle update \-\-all\fR, bundler will ignore any previously installed gems and resolve all dependencies again based on the latest versions of all gems available in the sources\. +. +.P +Consider the following Gemfile(5): +. +.IP "" 4 +. +.nf + +source "https://rubygems\.org" + +gem "rails", "3\.0\.0\.rc" +gem "nokogiri" +. +.fi +. +.IP "" 0 +. +.P +When you run bundle install(1) \fIbundle\-install\.1\.html\fR the first time, bundler will resolve all of the dependencies, all the way down, and install what you need: +. +.IP "" 4 +. +.nf + +Fetching gem metadata from https://rubygems\.org/\.\.\.\.\.\.\.\.\. +Resolving dependencies\.\.\. +Installing builder 2\.1\.2 +Installing abstract 1\.0\.0 +Installing rack 1\.2\.8 +Using bundler 1\.7\.6 +Installing rake 10\.4\.0 +Installing polyglot 0\.3\.5 +Installing mime\-types 1\.25\.1 +Installing i18n 0\.4\.2 +Installing mini_portile 0\.6\.1 +Installing tzinfo 0\.3\.42 +Installing rack\-mount 0\.6\.14 +Installing rack\-test 0\.5\.7 +Installing treetop 1\.4\.15 +Installing thor 0\.14\.6 +Installing activesupport 3\.0\.0\.rc +Installing erubis 2\.6\.6 +Installing activemodel 3\.0\.0\.rc +Installing arel 0\.4\.0 +Installing mail 2\.2\.20 +Installing activeresource 3\.0\.0\.rc +Installing actionpack 3\.0\.0\.rc +Installing activerecord 3\.0\.0\.rc +Installing actionmailer 3\.0\.0\.rc +Installing railties 3\.0\.0\.rc +Installing rails 3\.0\.0\.rc +Installing nokogiri 1\.6\.5 + +Bundle complete! 2 Gemfile dependencies, 26 gems total\. +Use `bundle show [gemname]` to see where a bundled gem is installed\. +. +.fi +. +.IP "" 0 +. +.P +As you can see, even though you have two gems in the Gemfile(5), your application needs 26 different gems in order to run\. Bundler remembers the exact versions it installed in \fBGemfile\.lock\fR\. The next time you run bundle install(1) \fIbundle\-install\.1\.html\fR, bundler skips the dependency resolution and installs the same gems as it installed last time\. +. +.P +After checking in the \fBGemfile\.lock\fR into version control and cloning it on another machine, running bundle install(1) \fIbundle\-install\.1\.html\fR will \fIstill\fR install the gems that you installed last time\. You don\'t need to worry that a new release of \fBerubis\fR or \fBmail\fR changes the gems you use\. +. +.P +However, from time to time, you might want to update the gems you are using to the newest versions that still match the gems in your Gemfile(5)\. +. +.P +To do this, run \fBbundle update \-\-all\fR, which will ignore the \fBGemfile\.lock\fR, and resolve all the dependencies again\. Keep in mind that this process can result in a significantly different set of the 25 gems, based on the requirements of new gems that the gem authors released since the last time you ran \fBbundle update \-\-all\fR\. +. +.SH "UPDATING A LIST OF GEMS" +Sometimes, you want to update a single gem in the Gemfile(5), and leave the rest of the gems that you specified locked to the versions in the \fBGemfile\.lock\fR\. +. +.P +For instance, in the scenario above, imagine that \fBnokogiri\fR releases version \fB1\.4\.4\fR, and you want to update it \fIwithout\fR updating Rails and all of its dependencies\. To do this, run \fBbundle update nokogiri\fR\. +. +.P +Bundler will update \fBnokogiri\fR and any of its dependencies, but leave alone Rails and its dependencies\. +. +.SH "OVERLAPPING DEPENDENCIES" +Sometimes, multiple gems declared in your Gemfile(5) are satisfied by the same second\-level dependency\. For instance, consider the case of \fBthin\fR and \fBrack\-perftools\-profiler\fR\. +. +.IP "" 4 +. +.nf + +source "https://rubygems\.org" + +gem "thin" +gem "rack\-perftools\-profiler" +. +.fi +. +.IP "" 0 +. +.P +The \fBthin\fR gem depends on \fBrack >= 1\.0\fR, while \fBrack\-perftools\-profiler\fR depends on \fBrack ~> 1\.0\fR\. If you run bundle install, you get: +. +.IP "" 4 +. +.nf + +Fetching source index for https://rubygems\.org/ +Installing daemons (1\.1\.0) +Installing eventmachine (0\.12\.10) with native extensions +Installing open4 (1\.0\.1) +Installing perftools\.rb (0\.4\.7) with native extensions +Installing rack (1\.2\.1) +Installing rack\-perftools_profiler (0\.0\.2) +Installing thin (1\.2\.7) with native extensions +Using bundler (1\.0\.0\.rc\.3) +. +.fi +. +.IP "" 0 +. +.P +In this case, the two gems have their own set of dependencies, but they share \fBrack\fR in common\. If you run \fBbundle update thin\fR, bundler will update \fBdaemons\fR, \fBeventmachine\fR and \fBrack\fR, which are dependencies of \fBthin\fR, but not \fBopen4\fR or \fBperftools\.rb\fR, which are dependencies of \fBrack\-perftools_profiler\fR\. Note that \fBbundle update thin\fR will update \fBrack\fR even though it\'s \fIalso\fR a dependency of \fBrack\-perftools_profiler\fR\. +. +.P +In short, by default, when you update a gem using \fBbundle update\fR, bundler will update all dependencies of that gem, including those that are also dependencies of another gem\. +. +.P +To prevent updating indirect dependencies, prior to version 1\.14 the only option was the \fBCONSERVATIVE UPDATING\fR behavior in bundle install(1) \fIbundle\-install\.1\.html\fR: +. +.P +In this scenario, updating the \fBthin\fR version manually in the Gemfile(5), and then running bundle install(1) \fIbundle\-install\.1\.html\fR will only update \fBdaemons\fR and \fBeventmachine\fR, but not \fBrack\fR\. For more information, see the \fBCONSERVATIVE UPDATING\fR section of bundle install(1) \fIbundle\-install\.1\.html\fR\. +. +.P +Starting with 1\.14, specifying the \fB\-\-conservative\fR option will also prevent indirect dependencies from being updated\. +. +.SH "PATCH LEVEL OPTIONS" +Version 1\.14 introduced 4 patch\-level options that will influence how gem versions are resolved\. One of the following options can be used: \fB\-\-patch\fR, \fB\-\-minor\fR or \fB\-\-major\fR\. \fB\-\-strict\fR can be added to further influence resolution\. +. +.TP +\fB\-\-patch\fR +Prefer updating only to next patch version\. +. +.TP +\fB\-\-minor\fR +Prefer updating only to next minor version\. +. +.TP +\fB\-\-major\fR +Prefer updating to next major version (default)\. +. +.TP +\fB\-\-strict\fR +Do not allow any gem to be updated past latest \fB\-\-patch\fR | \fB\-\-minor\fR | \fB\-\-major\fR\. +. +.P +When Bundler is resolving what versions to use to satisfy declared requirements in the Gemfile or in parent gems, it looks up all available versions, filters out any versions that don\'t satisfy the requirement, and then, by default, sorts them from newest to oldest, considering them in that order\. +. +.P +Providing one of the patch level options (e\.g\. \fB\-\-patch\fR) changes the sort order of the satisfying versions, causing Bundler to consider the latest \fB\-\-patch\fR or \fB\-\-minor\fR version available before other versions\. Note that versions outside the stated patch level could still be resolved to if necessary to find a suitable dependency graph\. +. +.P +For example, if gem \'foo\' is locked at 1\.0\.2, with no gem requirement defined in the Gemfile, and versions 1\.0\.3, 1\.0\.4, 1\.1\.0, 1\.1\.1, 2\.0\.0 all exist, the default order of preference by default (\fB\-\-major\fR) will be "2\.0\.0, 1\.1\.1, 1\.1\.0, 1\.0\.4, 1\.0\.3, 1\.0\.2"\. +. +.P +If the \fB\-\-patch\fR option is used, the order of preference will change to "1\.0\.4, 1\.0\.3, 1\.0\.2, 1\.1\.1, 1\.1\.0, 2\.0\.0"\. +. +.P +If the \fB\-\-minor\fR option is used, the order of preference will change to "1\.1\.1, 1\.1\.0, 1\.0\.4, 1\.0\.3, 1\.0\.2, 2\.0\.0"\. +. +.P +Combining the \fB\-\-strict\fR option with any of the patch level options will remove any versions beyond the scope of the patch level option, to ensure that no gem is updated that far\. +. +.P +To continue the previous example, if both \fB\-\-patch\fR and \fB\-\-strict\fR options are used, the available versions for resolution would be "1\.0\.4, 1\.0\.3, 1\.0\.2"\. If \fB\-\-minor\fR and \fB\-\-strict\fR are used, it would be "1\.1\.1, 1\.1\.0, 1\.0\.4, 1\.0\.3, 1\.0\.2"\. +. +.P +Gem requirements as defined in the Gemfile will still be the first determining factor for what versions are available\. If the gem requirement for \fBfoo\fR in the Gemfile is \'~> 1\.0\', that will accomplish the same thing as providing the \fB\-\-minor\fR and \fB\-\-strict\fR options\. +. +.SH "PATCH LEVEL EXAMPLES" +Given the following gem specifications: +. +.IP "" 4 +. +.nf + +foo 1\.4\.3, requires: ~> bar 2\.0 +foo 1\.4\.4, requires: ~> bar 2\.0 +foo 1\.4\.5, requires: ~> bar 2\.1 +foo 1\.5\.0, requires: ~> bar 2\.1 +foo 1\.5\.1, requires: ~> bar 3\.0 +bar with versions 2\.0\.3, 2\.0\.4, 2\.1\.0, 2\.1\.1, 3\.0\.0 +. +.fi +. +.IP "" 0 +. +.P +Gemfile: +. +.IP "" 4 +. +.nf + +gem \'foo\' +. +.fi +. +.IP "" 0 +. +.P +Gemfile\.lock: +. +.IP "" 4 +. +.nf + +foo (1\.4\.3) + bar (~> 2\.0) +bar (2\.0\.3) +. +.fi +. +.IP "" 0 +. +.P +Cases: +. +.IP "" 4 +. +.nf + +# Command Line Result +\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- +1 bundle update \-\-patch \'foo 1\.4\.5\', \'bar 2\.1\.1\' +2 bundle update \-\-patch foo \'foo 1\.4\.5\', \'bar 2\.1\.1\' +3 bundle update \-\-minor \'foo 1\.5\.1\', \'bar 3\.0\.0\' +4 bundle update \-\-minor \-\-strict \'foo 1\.5\.0\', \'bar 2\.1\.1\' +5 bundle update \-\-patch \-\-strict \'foo 1\.4\.4\', \'bar 2\.0\.4\' +. +.fi +. +.IP "" 0 +. +.P +In case 1, bar is upgraded to 2\.1\.1, a minor version increase, because the dependency from foo 1\.4\.5 required it\. +. +.P +In case 2, only foo is requested to be unlocked, but bar is also allowed to move because it\'s not a declared dependency in the Gemfile\. +. +.P +In case 3, bar goes up a whole major release, because a minor increase is preferred now for foo, and when it goes to 1\.5\.1, it requires 3\.0\.0 of bar\. +. +.P +In case 4, foo is preferred up to a minor version, but 1\.5\.1 won\'t work because the \-\-strict flag removes bar 3\.0\.0 from consideration since it\'s a major increment\. +. +.P +In case 5, both foo and bar have any minor or major increments removed from consideration because of the \-\-strict flag, so the most they can move is up to 1\.4\.4 and 2\.0\.4\. +. +.SH "RECOMMENDED WORKFLOW" +In general, when working with an application managed with bundler, you should use the following workflow: +. +.IP "\(bu" 4 +After you create your Gemfile(5) for the first time, run +. +.IP +$ bundle install +. +.IP "\(bu" 4 +Check the resulting \fBGemfile\.lock\fR into version control +. +.IP +$ git add Gemfile\.lock +. +.IP "\(bu" 4 +When checking out this repository on another development machine, run +. +.IP +$ bundle install +. +.IP "\(bu" 4 +When checking out this repository on a deployment machine, run +. +.IP +$ bundle install \-\-deployment +. +.IP "\(bu" 4 +After changing the Gemfile(5) to reflect a new or update dependency, run +. +.IP +$ bundle install +. +.IP "\(bu" 4 +Make sure to check the updated \fBGemfile\.lock\fR into version control +. +.IP +$ git add Gemfile\.lock +. +.IP "\(bu" 4 +If bundle install(1) \fIbundle\-install\.1\.html\fR reports a conflict, manually update the specific gems that you changed in the Gemfile(5) +. +.IP +$ bundle update rails thin +. +.IP "\(bu" 4 +If you want to update all the gems to the latest possible versions that still match the gems listed in the Gemfile(5), run +. +.IP +$ bundle update \-\-all +. +.IP "" 0 + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-update.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-update.1.ronn new file mode 100644 index 0000000..fe500cd --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-update.1.ronn @@ -0,0 +1,351 @@ +bundle-update(1) -- Update your gems to the latest available versions +===================================================================== + +## SYNOPSIS + +`bundle update` <*gems> [--all] + [--group=NAME] + [--source=NAME] + [--local] + [--ruby] + [--bundler[=VERSION]] + [--full-index] + [--jobs=JOBS] + [--quiet] + [--patch|--minor|--major] + [--redownload] + [--strict] + [--conservative] + +## DESCRIPTION + +Update the gems specified (all gems, if `--all` flag is used), ignoring +the previously installed gems specified in the `Gemfile.lock`. In +general, you should use [bundle install(1)](bundle-install.1.html) to install the same exact +gems and versions across machines. + +You would use `bundle update` to explicitly update the version of a +gem. + +## OPTIONS + +* `--all`: + Update all gems specified in Gemfile. + +* `--group=`, `-g=[]`: + Only update the gems in the specified group. For instance, you can update all gems + in the development group with `bundle update --group development`. You can also + call `bundle update rails --group test` to update the rails gem and all gems in + the test group, for example. + +* `--source=`: + The name of a `:git` or `:path` source used in the Gemfile(5). For + instance, with a `:git` source of `http://github.com/rails/rails.git`, + you would call `bundle update --source rails` + +* `--local`: + Do not attempt to fetch gems remotely and use the gem cache instead. + +* `--ruby`: + Update the locked version of Ruby to the current version of Ruby. + +* `--bundler`: + Update the locked version of bundler to the invoked bundler version. + +* `--full-index`: + Fall back to using the single-file index of all gems. + +* `--jobs=[]`, `-j[]`: + Specify the number of jobs to run in parallel. The default is the number of + available processors. + +* `--retry=[]`: + Retry failed network or git requests for times. + +* `--quiet`: + Only output warnings and errors. + +* `--redownload`: + Force downloading every gem. + +* `--patch`: + Prefer updating only to next patch version. + +* `--minor`: + Prefer updating only to next minor version. + +* `--major`: + Prefer updating to next major version (default). + +* `--strict`: + Do not allow any gem to be updated past latest `--patch` | `--minor` | `--major`. + +* `--conservative`: + Use bundle install conservative update behavior and do not allow indirect dependencies to be updated. + +## UPDATING ALL GEMS + +If you run `bundle update --all`, bundler will ignore +any previously installed gems and resolve all dependencies again +based on the latest versions of all gems available in the sources. + +Consider the following Gemfile(5): + + source "https://rubygems.org" + + gem "rails", "3.0.0.rc" + gem "nokogiri" + +When you run [bundle install(1)](bundle-install.1.html) the first time, bundler will resolve +all of the dependencies, all the way down, and install what you need: + + Fetching gem metadata from https://rubygems.org/......... + Resolving dependencies... + Installing builder 2.1.2 + Installing abstract 1.0.0 + Installing rack 1.2.8 + Using bundler 1.7.6 + Installing rake 10.4.0 + Installing polyglot 0.3.5 + Installing mime-types 1.25.1 + Installing i18n 0.4.2 + Installing mini_portile 0.6.1 + Installing tzinfo 0.3.42 + Installing rack-mount 0.6.14 + Installing rack-test 0.5.7 + Installing treetop 1.4.15 + Installing thor 0.14.6 + Installing activesupport 3.0.0.rc + Installing erubis 2.6.6 + Installing activemodel 3.0.0.rc + Installing arel 0.4.0 + Installing mail 2.2.20 + Installing activeresource 3.0.0.rc + Installing actionpack 3.0.0.rc + Installing activerecord 3.0.0.rc + Installing actionmailer 3.0.0.rc + Installing railties 3.0.0.rc + Installing rails 3.0.0.rc + Installing nokogiri 1.6.5 + + Bundle complete! 2 Gemfile dependencies, 26 gems total. + Use `bundle show [gemname]` to see where a bundled gem is installed. + +As you can see, even though you have two gems in the Gemfile(5), your application +needs 26 different gems in order to run. Bundler remembers the exact versions +it installed in `Gemfile.lock`. The next time you run [bundle install(1)](bundle-install.1.html), bundler skips +the dependency resolution and installs the same gems as it installed last time. + +After checking in the `Gemfile.lock` into version control and cloning it on another +machine, running [bundle install(1)](bundle-install.1.html) will _still_ install the gems that you installed +last time. You don't need to worry that a new release of `erubis` or `mail` changes +the gems you use. + +However, from time to time, you might want to update the gems you are using to the +newest versions that still match the gems in your Gemfile(5). + +To do this, run `bundle update --all`, which will ignore the `Gemfile.lock`, and resolve +all the dependencies again. Keep in mind that this process can result in a significantly +different set of the 25 gems, based on the requirements of new gems that the gem +authors released since the last time you ran `bundle update --all`. + +## UPDATING A LIST OF GEMS + +Sometimes, you want to update a single gem in the Gemfile(5), and leave the rest of the +gems that you specified locked to the versions in the `Gemfile.lock`. + +For instance, in the scenario above, imagine that `nokogiri` releases version `1.4.4`, and +you want to update it _without_ updating Rails and all of its dependencies. To do this, +run `bundle update nokogiri`. + +Bundler will update `nokogiri` and any of its dependencies, but leave alone Rails and +its dependencies. + +## OVERLAPPING DEPENDENCIES + +Sometimes, multiple gems declared in your Gemfile(5) are satisfied by the same +second-level dependency. For instance, consider the case of `thin` and +`rack-perftools-profiler`. + + source "https://rubygems.org" + + gem "thin" + gem "rack-perftools-profiler" + +The `thin` gem depends on `rack >= 1.0`, while `rack-perftools-profiler` depends +on `rack ~> 1.0`. If you run bundle install, you get: + + Fetching source index for https://rubygems.org/ + Installing daemons (1.1.0) + Installing eventmachine (0.12.10) with native extensions + Installing open4 (1.0.1) + Installing perftools.rb (0.4.7) with native extensions + Installing rack (1.2.1) + Installing rack-perftools_profiler (0.0.2) + Installing thin (1.2.7) with native extensions + Using bundler (1.0.0.rc.3) + +In this case, the two gems have their own set of dependencies, but they share +`rack` in common. If you run `bundle update thin`, bundler will update `daemons`, +`eventmachine` and `rack`, which are dependencies of `thin`, but not `open4` or +`perftools.rb`, which are dependencies of `rack-perftools_profiler`. Note that +`bundle update thin` will update `rack` even though it's _also_ a dependency of +`rack-perftools_profiler`. + +In short, by default, when you update a gem using `bundle update`, bundler will +update all dependencies of that gem, including those that are also dependencies +of another gem. + +To prevent updating indirect dependencies, prior to version 1.14 the only option +was the `CONSERVATIVE UPDATING` behavior in [bundle install(1)](bundle-install.1.html): + +In this scenario, updating the `thin` version manually in the Gemfile(5), +and then running [bundle install(1)](bundle-install.1.html) will only update `daemons` and `eventmachine`, +but not `rack`. For more information, see the `CONSERVATIVE UPDATING` section +of [bundle install(1)](bundle-install.1.html). + +Starting with 1.14, specifying the `--conservative` option will also prevent indirect +dependencies from being updated. + +## PATCH LEVEL OPTIONS + +Version 1.14 introduced 4 patch-level options that will influence how gem +versions are resolved. One of the following options can be used: `--patch`, +`--minor` or `--major`. `--strict` can be added to further influence resolution. + +* `--patch`: + Prefer updating only to next patch version. + +* `--minor`: + Prefer updating only to next minor version. + +* `--major`: + Prefer updating to next major version (default). + +* `--strict`: + Do not allow any gem to be updated past latest `--patch` | `--minor` | `--major`. + +When Bundler is resolving what versions to use to satisfy declared +requirements in the Gemfile or in parent gems, it looks up all +available versions, filters out any versions that don't satisfy +the requirement, and then, by default, sorts them from newest to +oldest, considering them in that order. + +Providing one of the patch level options (e.g. `--patch`) changes the +sort order of the satisfying versions, causing Bundler to consider the +latest `--patch` or `--minor` version available before other versions. +Note that versions outside the stated patch level could still be +resolved to if necessary to find a suitable dependency graph. + +For example, if gem 'foo' is locked at 1.0.2, with no gem requirement +defined in the Gemfile, and versions 1.0.3, 1.0.4, 1.1.0, 1.1.1, 2.0.0 +all exist, the default order of preference by default (`--major`) will +be "2.0.0, 1.1.1, 1.1.0, 1.0.4, 1.0.3, 1.0.2". + +If the `--patch` option is used, the order of preference will change to +"1.0.4, 1.0.3, 1.0.2, 1.1.1, 1.1.0, 2.0.0". + +If the `--minor` option is used, the order of preference will change to +"1.1.1, 1.1.0, 1.0.4, 1.0.3, 1.0.2, 2.0.0". + +Combining the `--strict` option with any of the patch level options +will remove any versions beyond the scope of the patch level option, +to ensure that no gem is updated that far. + +To continue the previous example, if both `--patch` and `--strict` +options are used, the available versions for resolution would be +"1.0.4, 1.0.3, 1.0.2". If `--minor` and `--strict` are used, it would +be "1.1.1, 1.1.0, 1.0.4, 1.0.3, 1.0.2". + +Gem requirements as defined in the Gemfile will still be the first +determining factor for what versions are available. If the gem +requirement for `foo` in the Gemfile is '~> 1.0', that will accomplish +the same thing as providing the `--minor` and `--strict` options. + +## PATCH LEVEL EXAMPLES + +Given the following gem specifications: + + foo 1.4.3, requires: ~> bar 2.0 + foo 1.4.4, requires: ~> bar 2.0 + foo 1.4.5, requires: ~> bar 2.1 + foo 1.5.0, requires: ~> bar 2.1 + foo 1.5.1, requires: ~> bar 3.0 + bar with versions 2.0.3, 2.0.4, 2.1.0, 2.1.1, 3.0.0 + +Gemfile: + + gem 'foo' + +Gemfile.lock: + + foo (1.4.3) + bar (~> 2.0) + bar (2.0.3) + +Cases: + + # Command Line Result + ------------------------------------------------------------ + 1 bundle update --patch 'foo 1.4.5', 'bar 2.1.1' + 2 bundle update --patch foo 'foo 1.4.5', 'bar 2.1.1' + 3 bundle update --minor 'foo 1.5.1', 'bar 3.0.0' + 4 bundle update --minor --strict 'foo 1.5.0', 'bar 2.1.1' + 5 bundle update --patch --strict 'foo 1.4.4', 'bar 2.0.4' + +In case 1, bar is upgraded to 2.1.1, a minor version increase, because +the dependency from foo 1.4.5 required it. + +In case 2, only foo is requested to be unlocked, but bar is also +allowed to move because it's not a declared dependency in the Gemfile. + +In case 3, bar goes up a whole major release, because a minor increase +is preferred now for foo, and when it goes to 1.5.1, it requires 3.0.0 +of bar. + +In case 4, foo is preferred up to a minor version, but 1.5.1 won't work +because the --strict flag removes bar 3.0.0 from consideration since +it's a major increment. + +In case 5, both foo and bar have any minor or major increments removed +from consideration because of the --strict flag, so the most they can +move is up to 1.4.4 and 2.0.4. + +## RECOMMENDED WORKFLOW + +In general, when working with an application managed with bundler, you should +use the following workflow: + +* After you create your Gemfile(5) for the first time, run + + $ bundle install + +* Check the resulting `Gemfile.lock` into version control + + $ git add Gemfile.lock + +* When checking out this repository on another development machine, run + + $ bundle install + +* When checking out this repository on a deployment machine, run + + $ bundle install --deployment + +* After changing the Gemfile(5) to reflect a new or update dependency, run + + $ bundle install + +* Make sure to check the updated `Gemfile.lock` into version control + + $ git add Gemfile.lock + +* If [bundle install(1)](bundle-install.1.html) reports a conflict, manually update the specific + gems that you changed in the Gemfile(5) + + $ bundle update rails thin + +* If you want to update all the gems to the latest possible versions that + still match the gems listed in the Gemfile(5), run + + $ bundle update --all diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-version.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-version.1 new file mode 100644 index 0000000..3721cf9 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-version.1 @@ -0,0 +1,35 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-VERSION" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-version\fR \- Prints Bundler version information +. +.SH "SYNOPSIS" +\fBbundle version\fR +. +.SH "DESCRIPTION" +Prints Bundler version information\. +. +.SH "OPTIONS" +No options\. +. +.SH "EXAMPLE" +Print the version of Bundler with build date and commit hash of the in the Git source\. +. +.IP "" 4 +. +.nf + +bundle version +. +.fi +. +.IP "" 0 +. +.P +shows \fBBundler version 2\.3\.21 (2022\-08\-24 commit d54be5fdd8)\fR for example\. +. +.P +cf\. \fBbundle \-\-version\fR shows \fBBundler version 2\.3\.21\fR\. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-version.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-version.1.ronn new file mode 100644 index 0000000..46c6f0b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-version.1.ronn @@ -0,0 +1,24 @@ +bundle-version(1) -- Prints Bundler version information +======================================================= + +## SYNOPSIS + +`bundle version` + +## DESCRIPTION + +Prints Bundler version information. + +## OPTIONS + +No options. + +## EXAMPLE + +Print the version of Bundler with build date and commit hash of the in the Git source. + + bundle version + +shows `Bundler version 2.3.21 (2022-08-24 commit d54be5fdd8)` for example. + +cf. `bundle --version` shows `Bundler version 2.3.21`. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-viz.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-viz.1 new file mode 100644 index 0000000..3508c09 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-viz.1 @@ -0,0 +1,42 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-VIZ" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile +. +.SH "SYNOPSIS" +\fBbundle viz\fR [\-\-file=FILE] [\-\-format=FORMAT] [\-\-requirements] [\-\-version] [\-\-without=GROUP GROUP] +. +.SH "DESCRIPTION" +\fBviz\fR generates a PNG file of the current \fBGemfile(5)\fR as a dependency graph\. \fBviz\fR requires the ruby\-graphviz gem (and its dependencies)\. +. +.P +The associated gems must also be installed via \fBbundle install(1)\fR \fIbundle\-install\.1\.html\fR\. +. +.P +\fBviz\fR command was deprecated in Bundler 2\.2\. Use bundler\-graph plugin \fIhttps://github\.com/rubygems/bundler\-graph\fR instead\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-file\fR, \fB\-f\fR +The name to use for the generated file\. See \fB\-\-format\fR option +. +.TP +\fB\-\-format\fR, \fB\-F\fR +This is output format option\. Supported format is png, jpg, svg, dot \.\.\. +. +.TP +\fB\-\-requirements\fR, \fB\-R\fR +Set to show the version of each required dependency\. +. +.TP +\fB\-\-version\fR, \fB\-v\fR +Set to show each gem version\. +. +.TP +\fB\-\-without\fR, \fB\-W\fR +Exclude gems that are part of the specified named group\. + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-viz.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-viz.1.ronn new file mode 100644 index 0000000..f220256 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle-viz.1.ronn @@ -0,0 +1,32 @@ +bundle-viz(1) -- Generates a visual dependency graph for your Gemfile +===================================================================== + +## SYNOPSIS + +`bundle viz` [--file=FILE] + [--format=FORMAT] + [--requirements] + [--version] + [--without=GROUP GROUP] + +## DESCRIPTION + +`viz` generates a PNG file of the current `Gemfile(5)` as a dependency graph. +`viz` requires the ruby-graphviz gem (and its dependencies). + +The associated gems must also be installed via [`bundle install(1)`](bundle-install.1.html). + +`viz` command was deprecated in Bundler 2.2. Use [bundler-graph plugin](https://github.com/rubygems/bundler-graph) instead. + +## OPTIONS + +* `--file`, `-f`: + The name to use for the generated file. See `--format` option +* `--format`, `-F`: + This is output format option. Supported format is png, jpg, svg, dot ... +* `--requirements`, `-R`: + Set to show the version of each required dependency. +* `--version`, `-v`: + Set to show each gem version. +* `--without`, `-W`: + Exclude gems that are part of the specified named group. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle.1 b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle.1 new file mode 100644 index 0000000..c2e7e4c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle.1 @@ -0,0 +1,141 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE" "1" "October 2022" "" "" +. +.SH "NAME" +\fBbundle\fR \- Ruby Dependency Management +. +.SH "SYNOPSIS" +\fBbundle\fR COMMAND [\-\-no\-color] [\-\-verbose] [ARGS] +. +.SH "DESCRIPTION" +Bundler manages an \fBapplication\'s dependencies\fR through its entire life across many machines systematically and repeatably\. +. +.P +See the bundler website \fIhttps://bundler\.io\fR for information on getting started, and Gemfile(5) for more information on the \fBGemfile\fR format\. +. +.SH "OPTIONS" +. +.TP +\fB\-\-no\-color\fR +Print all output without color +. +.TP +\fB\-\-retry\fR, \fB\-r\fR +Specify the number of times you wish to attempt network commands +. +.TP +\fB\-\-verbose\fR, \fB\-V\fR +Print out additional logging information +. +.SH "BUNDLE COMMANDS" +We divide \fBbundle\fR subcommands into primary commands and utilities: +. +.SH "PRIMARY COMMANDS" +. +.TP +\fBbundle install(1)\fR \fIbundle\-install\.1\.html\fR +Install the gems specified by the \fBGemfile\fR or \fBGemfile\.lock\fR +. +.TP +\fBbundle update(1)\fR \fIbundle\-update\.1\.html\fR +Update dependencies to their latest versions +. +.TP +\fBbundle cache(1)\fR \fIbundle\-cache\.1\.html\fR +Package the \.gem files required by your application into the \fBvendor/cache\fR directory (aliases: \fBbundle package\fR, \fBbundle pack\fR) +. +.TP +\fBbundle exec(1)\fR \fIbundle\-exec\.1\.html\fR +Execute a script in the current bundle +. +.TP +\fBbundle config(1)\fR \fIbundle\-config\.1\.html\fR +Specify and read configuration options for Bundler +. +.TP +\fBbundle help(1)\fR \fIbundle\-help\.1\.html\fR +Display detailed help for each subcommand +. +.SH "UTILITIES" +. +.TP +\fBbundle add(1)\fR \fIbundle\-add\.1\.html\fR +Add the named gem to the Gemfile and run \fBbundle install\fR +. +.TP +\fBbundle binstubs(1)\fR \fIbundle\-binstubs\.1\.html\fR +Generate binstubs for executables in a gem +. +.TP +\fBbundle check(1)\fR \fIbundle\-check\.1\.html\fR +Determine whether the requirements for your application are installed and available to Bundler +. +.TP +\fBbundle show(1)\fR \fIbundle\-show\.1\.html\fR +Show the source location of a particular gem in the bundle +. +.TP +\fBbundle outdated(1)\fR \fIbundle\-outdated\.1\.html\fR +Show all of the outdated gems in the current bundle +. +.TP +\fBbundle console(1)\fR (deprecated) +Start an IRB session in the current bundle +. +.TP +\fBbundle open(1)\fR \fIbundle\-open\.1\.html\fR +Open an installed gem in the editor +. +.TP +\fBbundle lock(1)\fR \fIbundle\-lock\.1\.html\fR +Generate a lockfile for your dependencies +. +.TP +\fBbundle viz(1)\fR \fIbundle\-viz\.1\.html\fR (deprecated) +Generate a visual representation of your dependencies +. +.TP +\fBbundle init(1)\fR \fIbundle\-init\.1\.html\fR +Generate a simple \fBGemfile\fR, placed in the current directory +. +.TP +\fBbundle gem(1)\fR \fIbundle\-gem\.1\.html\fR +Create a simple gem, suitable for development with Bundler +. +.TP +\fBbundle platform(1)\fR \fIbundle\-platform\.1\.html\fR +Display platform compatibility information +. +.TP +\fBbundle clean(1)\fR \fIbundle\-clean\.1\.html\fR +Clean up unused gems in your Bundler directory +. +.TP +\fBbundle doctor(1)\fR \fIbundle\-doctor\.1\.html\fR +Display warnings about common problems +. +.TP +\fBbundle remove(1)\fR \fIbundle\-remove\.1\.html\fR +Removes gems from the Gemfile +. +.TP +\fBbundle plugin(1)\fR \fIbundle\-plugin\.1\.html\fR +Manage Bundler plugins +. +.TP +\fBbundle version(1)\fR \fIbundle\-version\.1\.html\fR +Prints Bundler version information +. +.SH "PLUGINS" +When running a command that isn\'t listed in PRIMARY COMMANDS or UTILITIES, Bundler will try to find an executable on your path named \fBbundler\-\fR and execute it, passing down any extra arguments to it\. +. +.SH "OBSOLETE" +These commands are obsolete and should no longer be used: +. +.IP "\(bu" 4 +\fBbundle inject(1)\fR +. +.IP "" 0 + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/bundle.1.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle.1.ronn new file mode 100644 index 0000000..8245eff --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/bundle.1.ronn @@ -0,0 +1,116 @@ +bundle(1) -- Ruby Dependency Management +======================================= + +## SYNOPSIS + +`bundle` COMMAND [--no-color] [--verbose] [ARGS] + +## DESCRIPTION + +Bundler manages an `application's dependencies` through its entire life +across many machines systematically and repeatably. + +See [the bundler website](https://bundler.io) for information on getting +started, and Gemfile(5) for more information on the `Gemfile` format. + +## OPTIONS + +* `--no-color`: + Print all output without color + +* `--retry`, `-r`: + Specify the number of times you wish to attempt network commands + +* `--verbose`, `-V`: + Print out additional logging information + +## BUNDLE COMMANDS + +We divide `bundle` subcommands into primary commands and utilities: + +## PRIMARY COMMANDS + +* [`bundle install(1)`](bundle-install.1.html): + Install the gems specified by the `Gemfile` or `Gemfile.lock` + +* [`bundle update(1)`](bundle-update.1.html): + Update dependencies to their latest versions + +* [`bundle cache(1)`](bundle-cache.1.html): + Package the .gem files required by your application into the + `vendor/cache` directory (aliases: `bundle package`, `bundle pack`) + +* [`bundle exec(1)`](bundle-exec.1.html): + Execute a script in the current bundle + +* [`bundle config(1)`](bundle-config.1.html): + Specify and read configuration options for Bundler + +* [`bundle help(1)`](bundle-help.1.html): + Display detailed help for each subcommand + +## UTILITIES + +* [`bundle add(1)`](bundle-add.1.html): + Add the named gem to the Gemfile and run `bundle install` + +* [`bundle binstubs(1)`](bundle-binstubs.1.html): + Generate binstubs for executables in a gem + +* [`bundle check(1)`](bundle-check.1.html): + Determine whether the requirements for your application are installed + and available to Bundler + +* [`bundle show(1)`](bundle-show.1.html): + Show the source location of a particular gem in the bundle + +* [`bundle outdated(1)`](bundle-outdated.1.html): + Show all of the outdated gems in the current bundle + +* `bundle console(1)` (deprecated): + Start an IRB session in the current bundle + +* [`bundle open(1)`](bundle-open.1.html): + Open an installed gem in the editor + +* [`bundle lock(1)`](bundle-lock.1.html): + Generate a lockfile for your dependencies + +* [`bundle viz(1)`](bundle-viz.1.html) (deprecated): + Generate a visual representation of your dependencies + +* [`bundle init(1)`](bundle-init.1.html): + Generate a simple `Gemfile`, placed in the current directory + +* [`bundle gem(1)`](bundle-gem.1.html): + Create a simple gem, suitable for development with Bundler + +* [`bundle platform(1)`](bundle-platform.1.html): + Display platform compatibility information + +* [`bundle clean(1)`](bundle-clean.1.html): + Clean up unused gems in your Bundler directory + +* [`bundle doctor(1)`](bundle-doctor.1.html): + Display warnings about common problems + +* [`bundle remove(1)`](bundle-remove.1.html): + Removes gems from the Gemfile + +* [`bundle plugin(1)`](bundle-plugin.1.html): + Manage Bundler plugins + +* [`bundle version(1)`](bundle-version.1.html): + Prints Bundler version information + +## PLUGINS + +When running a command that isn't listed in PRIMARY COMMANDS or UTILITIES, +Bundler will try to find an executable on your path named `bundler-` +and execute it, passing down any extra arguments to it. + +## OBSOLETE + +These commands are obsolete and should no longer be used: + +* `bundle inject(1)` diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/gemfile.5 b/games/FNaFB2/Ruby/stdlib/bundler/man/gemfile.5 new file mode 100644 index 0000000..6fcffb9 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/gemfile.5 @@ -0,0 +1,723 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "GEMFILE" "5" "October 2022" "" "" +. +.SH "NAME" +\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs +. +.SH "SYNOPSIS" +A \fBGemfile\fR describes the gem dependencies required to execute associated Ruby code\. +. +.P +Place the \fBGemfile\fR in the root of the directory containing the associated code\. For instance, in a Rails application, place the \fBGemfile\fR in the same directory as the \fBRakefile\fR\. +. +.SH "SYNTAX" +A \fBGemfile\fR is evaluated as Ruby code, in a context which makes available a number of methods used to describe the gem requirements\. +. +.SH "GLOBAL SOURCE" +At the top of the \fBGemfile\fR, add a single line for the \fBRubyGems\fR source that contains the gems listed in the \fBGemfile\fR\. +. +.IP "" 4 +. +.nf + +source "https://rubygems\.org" +. +.fi +. +.IP "" 0 +. +.P +You can add only one global source\. In Bundler 1\.13, adding multiple global sources was deprecated\. The \fBsource\fR \fBMUST\fR be a valid RubyGems repository\. +. +.P +To use more than one source of RubyGems, you should use \fI\fBsource\fR block\fR\. +. +.P +A source is checked for gems following the heuristics described in \fISOURCE PRIORITY\fR\. +. +.P +\fBNote about a behavior of the feature deprecated in Bundler 1\.13\fR: If a gem is found in more than one global source, Bundler will print a warning after installing the gem indicating which source was used, and listing the other sources where the gem is available\. A specific source can be selected for gems that need to use a non\-standard repository, suppressing this warning, by using the \fI\fB:source\fR option\fR or \fBsource\fR block\. +. +.SS "CREDENTIALS" +Some gem sources require a username and password\. Use bundle config(1) \fIbundle\-config\.1\.html\fR to set the username and password for any of the sources that need it\. The command must be run once on each computer that will install the Gemfile, but this keeps the credentials from being stored in plain text in version control\. +. +.IP "" 4 +. +.nf + +bundle config gems\.example\.com user:password +. +.fi +. +.IP "" 0 +. +.P +For some sources, like a company Gemfury account, it may be easier to include the credentials in the Gemfile as part of the source URL\. +. +.IP "" 4 +. +.nf + +source "https://user:password@gems\.example\.com" +. +.fi +. +.IP "" 0 +. +.P +Credentials in the source URL will take precedence over credentials set using \fBconfig\fR\. +. +.SH "RUBY" +If your application requires a specific Ruby version or engine, specify your requirements using the \fBruby\fR method, with the following arguments\. All parameters are \fBOPTIONAL\fR unless otherwise specified\. +. +.SS "VERSION (required)" +The version of Ruby that your application requires\. If your application requires an alternate Ruby engine, such as JRuby, TruffleRuby, etc\., this should be the Ruby version that the engine is compatible with\. +. +.IP "" 4 +. +.nf + +ruby "3\.1\.2" +. +.fi +. +.IP "" 0 +. +.SS "ENGINE" +Each application \fImay\fR specify a Ruby engine\. If an engine is specified, an engine version \fImust\fR also be specified\. +. +.P +What exactly is an Engine? \- A Ruby engine is an implementation of the Ruby language\. +. +.IP "\(bu" 4 +For background: the reference or original implementation of the Ruby programming language is called Matz\'s Ruby Interpreter \fIhttps://en\.wikipedia\.org/wiki/Ruby_MRI\fR, or MRI for short\. This is named after Ruby creator Yukihiro Matsumoto, also known as Matz\. MRI is also known as CRuby, because it is written in C\. MRI is the most widely used Ruby engine\. +. +.IP "\(bu" 4 +Other implementations \fIhttps://www\.ruby\-lang\.org/en/about/\fR of Ruby exist\. Some of the more well\-known implementations include JRuby \fIhttp://jruby\.org/\fR and TruffleRuby \fIhttps://www\.graalvm\.org/ruby/\fR\. Rubinius is an alternative implementation of Ruby written in Ruby\. JRuby is an implementation of Ruby on the JVM, short for Java Virtual Machine\. TruffleRuby is a Ruby implementation on the GraalVM, a language toolkit built on the JVM\. +. +.IP "" 0 +. +.SS "ENGINE VERSION" +Each application \fImay\fR specify a Ruby engine version\. If an engine version is specified, an engine \fImust\fR also be specified\. If the engine is "ruby" the engine version specified \fImust\fR match the Ruby version\. +. +.IP "" 4 +. +.nf + +ruby "2\.6\.8", engine: "jruby", engine_version: "9\.3\.8\.0" +. +.fi +. +.IP "" 0 +. +.SS "PATCHLEVEL" +Each application \fImay\fR specify a Ruby patchlevel\. Specifying the patchlevel has been meaningless since Ruby 2\.1\.0 was released as the patchlevel is now uniquely determined by a combination of major, minor, and teeny version numbers\. +. +.P +This option was implemented in Bundler 1\.4\.0 for Ruby 2\.0 or earlier\. +. +.IP "" 4 +. +.nf + +ruby "3\.1\.2", patchlevel: "20" +. +.fi +. +.IP "" 0 +. +.SH "GEMS" +Specify gem requirements using the \fBgem\fR method, with the following arguments\. All parameters are \fBOPTIONAL\fR unless otherwise specified\. +. +.SS "NAME (required)" +For each gem requirement, list a single \fIgem\fR line\. +. +.IP "" 4 +. +.nf + +gem "nokogiri" +. +.fi +. +.IP "" 0 +. +.SS "VERSION" +Each \fIgem\fR \fBMAY\fR have one or more version specifiers\. +. +.IP "" 4 +. +.nf + +gem "nokogiri", ">= 1\.4\.2" +gem "RedCloth", ">= 4\.1\.0", "< 4\.2\.0" +. +.fi +. +.IP "" 0 +. +.SS "REQUIRE AS" +Each \fIgem\fR \fBMAY\fR specify files that should be used when autorequiring via \fBBundler\.require\fR\. You may pass an array with multiple files or \fBtrue\fR if the file you want \fBrequired\fR has the same name as \fIgem\fR or \fBfalse\fR to prevent any file from being autorequired\. +. +.IP "" 4 +. +.nf + +gem "redis", require: ["redis/connection/hiredis", "redis"] +gem "webmock", require: false +gem "byebug", require: true +. +.fi +. +.IP "" 0 +. +.P +The argument defaults to the name of the gem\. For example, these are identical: +. +.IP "" 4 +. +.nf + +gem "nokogiri" +gem "nokogiri", require: "nokogiri" +gem "nokogiri", require: true +. +.fi +. +.IP "" 0 +. +.SS "GROUPS" +Each \fIgem\fR \fBMAY\fR specify membership in one or more groups\. Any \fIgem\fR that does not specify membership in any group is placed in the \fBdefault\fR group\. +. +.IP "" 4 +. +.nf + +gem "rspec", group: :test +gem "wirble", groups: [:development, :test] +. +.fi +. +.IP "" 0 +. +.P +The Bundler runtime allows its two main methods, \fBBundler\.setup\fR and \fBBundler\.require\fR, to limit their impact to particular groups\. +. +.IP "" 4 +. +.nf + +# setup adds gems to Ruby\'s load path +Bundler\.setup # defaults to all groups +require "bundler/setup" # same as Bundler\.setup +Bundler\.setup(:default) # only set up the _default_ group +Bundler\.setup(:test) # only set up the _test_ group (but `not` _default_) +Bundler\.setup(:default, :test) # set up the _default_ and _test_ groups, but no others + +# require requires all of the gems in the specified groups +Bundler\.require # defaults to the _default_ group +Bundler\.require(:default) # identical +Bundler\.require(:default, :test) # requires the _default_ and _test_ groups +Bundler\.require(:test) # requires the _test_ group +. +.fi +. +.IP "" 0 +. +.P +The Bundler CLI allows you to specify a list of groups whose gems \fBbundle install\fR should not install with the \fBwithout\fR configuration\. +. +.P +To specify multiple groups to ignore, specify a list of groups separated by spaces\. +. +.IP "" 4 +. +.nf + +bundle config set \-\-local without test +bundle config set \-\-local without development test +. +.fi +. +.IP "" 0 +. +.P +Also, calling \fBBundler\.setup\fR with no parameters, or calling \fBrequire "bundler/setup"\fR will setup all groups except for the ones you excluded via \fB\-\-without\fR (since they are not available)\. +. +.P +Note that on \fBbundle install\fR, bundler downloads and evaluates all gems, in order to create a single canonical list of all of the required gems and their dependencies\. This means that you cannot list different versions of the same gems in different groups\. For more details, see Understanding Bundler \fIhttps://bundler\.io/rationale\.html\fR\. +. +.SS "PLATFORMS" +If a gem should only be used in a particular platform or set of platforms, you can specify them\. Platforms are essentially identical to groups, except that you do not need to use the \fB\-\-without\fR install\-time flag to exclude groups of gems for other platforms\. +. +.P +There are a number of \fBGemfile\fR platforms: +. +.TP +\fBruby\fR +C Ruby (MRI), Rubinius, or TruffleRuby, but not Windows +. +.TP +\fBmri\fR +C Ruby (MRI) only, but not Windows +. +.TP +\fBwindows\fR +Windows C Ruby (MRI), including RubyInstaller 32\-bit and 64\-bit versions +. +.TP +\fBmswin\fR +Windows C Ruby (MRI), including RubyInstaller 32\-bit versions +. +.TP +\fBmswin64\fR +Windows C Ruby (MRI), including RubyInstaller 64\-bit versions +. +.TP +\fBrbx\fR +Rubinius +. +.TP +\fBjruby\fR +JRuby +. +.TP +\fBtruffleruby\fR +TruffleRuby +. +.P +On platforms \fBruby\fR, \fBmri\fR, \fBmswin\fR, \fBmswin64\fR, and \fBwindows\fR, you may additionally specify a version by appending the major and minor version numbers without a delimiter\. For example, to specify that a gem should only be used on platform \fBruby\fR version 3\.1, use: +. +.IP "" 4 +. +.nf + +ruby_31 +. +.fi +. +.IP "" 0 +. +.P +As with groups (above), you may specify one or more platforms: +. +.IP "" 4 +. +.nf + +gem "weakling", platforms: :jruby +gem "ruby\-debug", platforms: :mri_31 +gem "nokogiri", platforms: [:windows_31, :jruby] +. +.fi +. +.IP "" 0 +. +.P +All operations involving groups (\fBbundle install\fR \fIbundle\-install\.1\.html\fR, \fBBundler\.setup\fR, \fBBundler\.require\fR) behave exactly the same as if any groups not matching the current platform were explicitly excluded\. +. +.SS "FORCE_RUBY_PLATFORM" +If you always want the pure ruby variant of a gem to be chosen over platform specific variants, you can use the \fBforce_ruby_platform\fR option: +. +.IP "" 4 +. +.nf + +gem "ffi", force_ruby_platform: true +. +.fi +. +.IP "" 0 +. +.P +This can be handy (assuming the pure ruby variant works fine) when: +. +.IP "\(bu" 4 +You\'re having issues with the platform specific variant\. +. +.IP "\(bu" 4 +The platform specific variant does not yet support a newer ruby (and thus has a \fBrequired_ruby_version\fR upper bound), but you still want your Gemfile{\.lock} files to resolve under that ruby\. +. +.IP "" 0 +. +.SS "SOURCE" +You can select an alternate RubyGems repository for a gem using the \':source\' option\. +. +.IP "" 4 +. +.nf + +gem "some_internal_gem", source: "https://gems\.example\.com" +. +.fi +. +.IP "" 0 +. +.P +This forces the gem to be loaded from this source and ignores the global source declared at the top level of the file\. If the gem does not exist in this source, it will not be installed\. +. +.P +Bundler will search for child dependencies of this gem by first looking in the source selected for the parent, but if they are not found there, it will fall back on the global source\. +. +.P +\fBNote about a behavior of the feature deprecated in Bundler 1\.13\fR: Selecting a specific source repository this way also suppresses the ambiguous gem warning described above in \fIGLOBAL SOURCE\fR\. +. +.P +Using the \fB:source\fR option for an individual gem will also make that source available as a possible global source for any other gems which do not specify explicit sources\. Thus, when adding gems with explicit sources, it is recommended that you also ensure all other gems in the Gemfile are using explicit sources\. +. +.SS "GIT" +If necessary, you can specify that a gem is located at a particular git repository using the \fB:git\fR parameter\. The repository can be accessed via several protocols: +. +.TP +\fBHTTP(S)\fR +gem "rails", git: "https://github\.com/rails/rails\.git" +. +.TP +\fBSSH\fR +gem "rails", git: "git@github\.com:rails/rails\.git" +. +.TP +\fBgit\fR +gem "rails", git: "git://github\.com/rails/rails\.git" +. +.P +If using SSH, the user that you use to run \fBbundle install\fR \fBMUST\fR have the appropriate keys available in their \fB$HOME/\.ssh\fR\. +. +.P +\fBNOTE\fR: \fBhttp://\fR and \fBgit://\fR URLs should be avoided if at all possible\. These protocols are unauthenticated, so a man\-in\-the\-middle attacker can deliver malicious code and compromise your system\. HTTPS and SSH are strongly preferred\. +. +.P +The \fBgroup\fR, \fBplatforms\fR, and \fBrequire\fR options are available and behave exactly the same as they would for a normal gem\. +. +.P +A git repository \fBSHOULD\fR have at least one file, at the root of the directory containing the gem, with the extension \fB\.gemspec\fR\. This file \fBMUST\fR contain a valid gem specification, as expected by the \fBgem build\fR command\. +. +.P +If a git repository does not have a \fB\.gemspec\fR, bundler will attempt to create one, but it will not contain any dependencies, executables, or C extension compilation instructions\. As a result, it may fail to properly integrate into your application\. +. +.P +If a git repository does have a \fB\.gemspec\fR for the gem you attached it to, a version specifier, if provided, means that the git repository is only valid if the \fB\.gemspec\fR specifies a version matching the version specifier\. If not, bundler will print a warning\. +. +.IP "" 4 +. +.nf + +gem "rails", "2\.3\.8", git: "https://github\.com/rails/rails\.git" +# bundle install will fail, because the \.gemspec in the rails +# repository\'s master branch specifies version 3\.0\.0 +. +.fi +. +.IP "" 0 +. +.P +If a git repository does \fBnot\fR have a \fB\.gemspec\fR for the gem you attached it to, a version specifier \fBMUST\fR be provided\. Bundler will use this version in the simple \fB\.gemspec\fR it creates\. +. +.P +Git repositories support a number of additional options\. +. +.TP +\fBbranch\fR, \fBtag\fR, and \fBref\fR +You \fBMUST\fR only specify at most one of these options\. The default is \fBbranch: "master"\fR\. For example: +. +.IP +gem "rails", git: "https://github\.com/rails/rails\.git", branch: "5\-0\-stable" +. +.IP +gem "rails", git: "https://github\.com/rails/rails\.git", tag: "v5\.0\.0" +. +.IP +gem "rails", git: "https://github\.com/rails/rails\.git", ref: "4aded" +. +.TP +\fBsubmodules\fR +For reference, a git submodule \fIhttps://git\-scm\.com/book/en/v2/Git\-Tools\-Submodules\fR lets you have another git repository within a subfolder of your repository\. Specify \fBsubmodules: true\fR to cause bundler to expand any submodules included in the git repository +. +.P +If a git repository contains multiple \fB\.gemspecs\fR, each \fB\.gemspec\fR represents a gem located at the same place in the file system as the \fB\.gemspec\fR\. +. +.IP "" 4 +. +.nf + +|~rails [git root] +| |\-rails\.gemspec [rails gem located here] +|~actionpack +| |\-actionpack\.gemspec [actionpack gem located here] +|~activesupport +| |\-activesupport\.gemspec [activesupport gem located here] +|\.\.\. +. +.fi +. +.IP "" 0 +. +.P +To install a gem located in a git repository, bundler changes to the directory containing the gemspec, runs \fBgem build name\.gemspec\fR and then installs the resulting gem\. The \fBgem build\fR command, which comes standard with Rubygems, evaluates the \fB\.gemspec\fR in the context of the directory in which it is located\. +. +.SS "GIT SOURCE" +A custom git source can be defined via the \fBgit_source\fR method\. Provide the source\'s name as an argument, and a block which receives a single argument and interpolates it into a string to return the full repo address: +. +.IP "" 4 +. +.nf + +git_source(:stash){ |repo_name| "https://stash\.corp\.acme\.pl/#{repo_name}\.git" } +gem \'rails\', stash: \'forks/rails\' +. +.fi +. +.IP "" 0 +. +.P +In addition, if you wish to choose a specific branch: +. +.IP "" 4 +. +.nf + +gem "rails", stash: "forks/rails", branch: "branch_name" +. +.fi +. +.IP "" 0 +. +.SS "GITHUB" +\fBNOTE\fR: This shorthand should be avoided until Bundler 2\.0, since it currently expands to an insecure \fBgit://\fR URL\. This allows a man\-in\-the\-middle attacker to compromise your system\. +. +.P +If the git repository you want to use is hosted on GitHub and is public, you can use the :github shorthand to specify the github username and repository name (without the trailing "\.git"), separated by a slash\. If both the username and repository name are the same, you can omit one\. +. +.IP "" 4 +. +.nf + +gem "rails", github: "rails/rails" +gem "rails", github: "rails" +. +.fi +. +.IP "" 0 +. +.P +Are both equivalent to +. +.IP "" 4 +. +.nf + +gem "rails", git: "https://github\.com/rails/rails\.git" +. +.fi +. +.IP "" 0 +. +.P +Since the \fBgithub\fR method is a specialization of \fBgit_source\fR, it accepts a \fB:branch\fR named argument\. +. +.P +You can also directly pass a pull request URL: +. +.IP "" 4 +. +.nf + +gem "rails", github: "https://github\.com/rails/rails/pull/43753" +. +.fi +. +.IP "" 0 +. +.P +Which is equivalent to: +. +.IP "" 4 +. +.nf + +gem "rails", github: "rails/rails", branch: "refs/pull/43753/head" +. +.fi +. +.IP "" 0 +. +.SS "GIST" +If the git repository you want to use is hosted as a GitHub Gist and is public, you can use the :gist shorthand to specify the gist identifier (without the trailing "\.git")\. +. +.IP "" 4 +. +.nf + +gem "the_hatch", gist: "4815162342" +. +.fi +. +.IP "" 0 +. +.P +Is equivalent to: +. +.IP "" 4 +. +.nf + +gem "the_hatch", git: "https://gist\.github\.com/4815162342\.git" +. +.fi +. +.IP "" 0 +. +.P +Since the \fBgist\fR method is a specialization of \fBgit_source\fR, it accepts a \fB:branch\fR named argument\. +. +.SS "BITBUCKET" +If the git repository you want to use is hosted on Bitbucket and is public, you can use the :bitbucket shorthand to specify the bitbucket username and repository name (without the trailing "\.git"), separated by a slash\. If both the username and repository name are the same, you can omit one\. +. +.IP "" 4 +. +.nf + +gem "rails", bitbucket: "rails/rails" +gem "rails", bitbucket: "rails" +. +.fi +. +.IP "" 0 +. +.P +Are both equivalent to +. +.IP "" 4 +. +.nf + +gem "rails", git: "https://rails@bitbucket\.org/rails/rails\.git" +. +.fi +. +.IP "" 0 +. +.P +Since the \fBbitbucket\fR method is a specialization of \fBgit_source\fR, it accepts a \fB:branch\fR named argument\. +. +.SS "PATH" +You can specify that a gem is located in a particular location on the file system\. Relative paths are resolved relative to the directory containing the \fBGemfile\fR\. +. +.P +Similar to the semantics of the \fB:git\fR option, the \fB:path\fR option requires that the directory in question either contains a \fB\.gemspec\fR for the gem, or that you specify an explicit version that bundler should use\. +. +.P +Unlike \fB:git\fR, bundler does not compile C extensions for gems specified as paths\. +. +.IP "" 4 +. +.nf + +gem "rails", path: "vendor/rails" +. +.fi +. +.IP "" 0 +. +.P +If you would like to use multiple local gems directly from the filesystem, you can set a global \fBpath\fR option to the path containing the gem\'s files\. This will automatically load gemspec files from subdirectories\. +. +.IP "" 4 +. +.nf + +path \'components\' do + gem \'admin_ui\' + gem \'public_ui\' +end +. +.fi +. +.IP "" 0 +. +.SH "BLOCK FORM OF SOURCE, GIT, PATH, GROUP and PLATFORMS" +The \fB:source\fR, \fB:git\fR, \fB:path\fR, \fB:group\fR, and \fB:platforms\fR options may be applied to a group of gems by using block form\. +. +.IP "" 4 +. +.nf + +source "https://gems\.example\.com" do + gem "some_internal_gem" + gem "another_internal_gem" +end + +git "https://github\.com/rails/rails\.git" do + gem "activesupport" + gem "actionpack" +end + +platforms :ruby do + gem "ruby\-debug" + gem "sqlite3" +end + +group :development, optional: true do + gem "wirble" + gem "faker" +end +. +.fi +. +.IP "" 0 +. +.P +In the case of the group block form the :optional option can be given to prevent a group from being installed unless listed in the \fB\-\-with\fR option given to the \fBbundle install\fR command\. +. +.P +In the case of the \fBgit\fR block form, the \fB:ref\fR, \fB:branch\fR, \fB:tag\fR, and \fB:submodules\fR options may be passed to the \fBgit\fR method, and all gems in the block will inherit those options\. +. +.P +The presence of a \fBsource\fR block in a Gemfile also makes that source available as a possible global source for any other gems which do not specify explicit sources\. Thus, when defining source blocks, it is recommended that you also ensure all other gems in the Gemfile are using explicit sources, either via source blocks or \fB:source\fR directives on individual gems\. +. +.SH "INSTALL_IF" +The \fBinstall_if\fR method allows gems to be installed based on a proc or lambda\. This is especially useful for optional gems that can only be used if certain software is installed or some other conditions are met\. +. +.IP "" 4 +. +.nf + +install_if \-> { RUBY_PLATFORM =~ /darwin/ } do + gem "pasteboard" +end +. +.fi +. +.IP "" 0 +. +.SH "GEMSPEC" +The \fB\.gemspec\fR \fIhttp://guides\.rubygems\.org/specification\-reference/\fR file is where you provide metadata about your gem to Rubygems\. Some required Gemspec attributes include the name, description, and homepage of your gem\. This is also where you specify the dependencies your gem needs to run\. +. +.P +If you wish to use Bundler to help install dependencies for a gem while it is being developed, use the \fBgemspec\fR method to pull in the dependencies listed in the \fB\.gemspec\fR file\. +. +.P +The \fBgemspec\fR method adds any runtime dependencies as gem requirements in the default group\. It also adds development dependencies as gem requirements in the \fBdevelopment\fR group\. Finally, it adds a gem requirement on your project (\fBpath: \'\.\'\fR)\. In conjunction with \fBBundler\.setup\fR, this allows you to require project files in your test code as you would if the project were installed as a gem; you need not manipulate the load path manually or require project files via relative paths\. +. +.P +The \fBgemspec\fR method supports optional \fB:path\fR, \fB:glob\fR, \fB:name\fR, and \fB:development_group\fR options, which control where bundler looks for the \fB\.gemspec\fR, the glob it uses to look for the gemspec (defaults to: "{,\fI,\fR/*}\.gemspec"), what named \fB\.gemspec\fR it uses (if more than one is present), and which group development dependencies are included in\. +. +.P +When a \fBgemspec\fR dependency encounters version conflicts during resolution, the local version under development will always be selected \-\- even if there are remote versions that better match other requirements for the \fBgemspec\fR gem\. +. +.SH "SOURCE PRIORITY" +When attempting to locate a gem to satisfy a gem requirement, bundler uses the following priority order: +. +.IP "1." 4 +The source explicitly attached to the gem (using \fB:source\fR, \fB:path\fR, or \fB:git\fR) +. +.IP "2." 4 +For implicit gems (dependencies of explicit gems), any source, git, or path repository declared on the parent\. This results in bundler prioritizing the ActiveSupport gem from the Rails git repository over ones from \fBrubygems\.org\fR +. +.IP "3." 4 +If neither of the above conditions are met, the global source will be used\. If multiple global sources are specified, they will be prioritized from last to first, but this is deprecated since Bundler 1\.13, so Bundler prints a warning and will abort with an error in the future\. +. +.IP "" 0 + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/man/gemfile.5.ronn b/games/FNaFB2/Ruby/stdlib/bundler/man/gemfile.5.ronn new file mode 100644 index 0000000..a3affc3 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/man/gemfile.5.ronn @@ -0,0 +1,538 @@ +Gemfile(5) -- A format for describing gem dependencies for Ruby programs +======================================================================== + +## SYNOPSIS + +A `Gemfile` describes the gem dependencies required to execute associated +Ruby code. + +Place the `Gemfile` in the root of the directory containing the associated +code. For instance, in a Rails application, place the `Gemfile` in the same +directory as the `Rakefile`. + +## SYNTAX + +A `Gemfile` is evaluated as Ruby code, in a context which makes available +a number of methods used to describe the gem requirements. + +## GLOBAL SOURCE + +At the top of the `Gemfile`, add a single line for the `RubyGems` source that +contains the gems listed in the `Gemfile`. + + source "https://rubygems.org" + +You can add only one global source. In Bundler 1.13, adding multiple global +sources was deprecated. The `source` `MUST` be a valid RubyGems repository. + +To use more than one source of RubyGems, you should use [`source` block +](#BLOCK-FORM-OF-SOURCE-GIT-PATH-GROUP-and-PLATFORMS). + +A source is checked for gems following the heuristics described in +[SOURCE PRIORITY][]. + +**Note about a behavior of the feature deprecated in Bundler 1.13**: +If a gem is found in more than one global source, Bundler +will print a warning after installing the gem indicating which source was used, +and listing the other sources where the gem is available. A specific source can +be selected for gems that need to use a non-standard repository, suppressing +this warning, by using the [`:source` option](#SOURCE) or `source` block. + +### CREDENTIALS + +Some gem sources require a username and password. Use [bundle config(1)](bundle-config.1.html) to set +the username and password for any of the sources that need it. The command must +be run once on each computer that will install the Gemfile, but this keeps the +credentials from being stored in plain text in version control. + + bundle config gems.example.com user:password + +For some sources, like a company Gemfury account, it may be easier to +include the credentials in the Gemfile as part of the source URL. + + source "https://user:password@gems.example.com" + +Credentials in the source URL will take precedence over credentials set using +`config`. + +## RUBY + +If your application requires a specific Ruby version or engine, specify your +requirements using the `ruby` method, with the following arguments. +All parameters are `OPTIONAL` unless otherwise specified. + +### VERSION (required) + +The version of Ruby that your application requires. If your application +requires an alternate Ruby engine, such as JRuby, TruffleRuby, etc., this +should be the Ruby version that the engine is compatible with. + + ruby "3.1.2" + +### ENGINE + +Each application _may_ specify a Ruby engine. If an engine is specified, an +engine version _must_ also be specified. + +What exactly is an Engine? + - A Ruby engine is an implementation of the Ruby language. + + - For background: the reference or original implementation of the Ruby + programming language is called + [Matz's Ruby Interpreter](https://en.wikipedia.org/wiki/Ruby_MRI), or MRI + for short. This is named after Ruby creator Yukihiro Matsumoto, + also known as Matz. MRI is also known as CRuby, because it is written in C. + MRI is the most widely used Ruby engine. + + - [Other implementations](https://www.ruby-lang.org/en/about/) of Ruby exist. + Some of the more well-known implementations include + [JRuby](http://jruby.org/) and [TruffleRuby](https://www.graalvm.org/ruby/). + Rubinius is an alternative implementation of Ruby written in Ruby. + JRuby is an implementation of Ruby on the JVM, short for Java Virtual Machine. + TruffleRuby is a Ruby implementation on the GraalVM, a language toolkit built on the JVM. + +### ENGINE VERSION + +Each application _may_ specify a Ruby engine version. If an engine version is +specified, an engine _must_ also be specified. If the engine is "ruby" the +engine version specified _must_ match the Ruby version. + + ruby "2.6.8", engine: "jruby", engine_version: "9.3.8.0" + +### PATCHLEVEL + +Each application _may_ specify a Ruby patchlevel. Specifying the patchlevel has +been meaningless since Ruby 2.1.0 was released as the patchlevel is now +uniquely determined by a combination of major, minor, and teeny version numbers. + +This option was implemented in Bundler 1.4.0 for Ruby 2.0 or earlier. + + ruby "3.1.2", patchlevel: "20" + +## GEMS + +Specify gem requirements using the `gem` method, with the following arguments. +All parameters are `OPTIONAL` unless otherwise specified. + +### NAME (required) + +For each gem requirement, list a single _gem_ line. + + gem "nokogiri" + +### VERSION + +Each _gem_ `MAY` have one or more version specifiers. + + gem "nokogiri", ">= 1.4.2" + gem "RedCloth", ">= 4.1.0", "< 4.2.0" + +### REQUIRE AS + +Each _gem_ `MAY` specify files that should be used when autorequiring via +`Bundler.require`. You may pass an array with multiple files or `true` if the file +you want `required` has the same name as _gem_ or `false` to +prevent any file from being autorequired. + + gem "redis", require: ["redis/connection/hiredis", "redis"] + gem "webmock", require: false + gem "byebug", require: true + +The argument defaults to the name of the gem. For example, these are identical: + + gem "nokogiri" + gem "nokogiri", require: "nokogiri" + gem "nokogiri", require: true + +### GROUPS + +Each _gem_ `MAY` specify membership in one or more groups. Any _gem_ that does +not specify membership in any group is placed in the `default` group. + + gem "rspec", group: :test + gem "wirble", groups: [:development, :test] + +The Bundler runtime allows its two main methods, `Bundler.setup` and +`Bundler.require`, to limit their impact to particular groups. + + # setup adds gems to Ruby's load path + Bundler.setup # defaults to all groups + require "bundler/setup" # same as Bundler.setup + Bundler.setup(:default) # only set up the _default_ group + Bundler.setup(:test) # only set up the _test_ group (but `not` _default_) + Bundler.setup(:default, :test) # set up the _default_ and _test_ groups, but no others + + # require requires all of the gems in the specified groups + Bundler.require # defaults to the _default_ group + Bundler.require(:default) # identical + Bundler.require(:default, :test) # requires the _default_ and _test_ groups + Bundler.require(:test) # requires the _test_ group + +The Bundler CLI allows you to specify a list of groups whose gems `bundle install` should +not install with the `without` configuration. + +To specify multiple groups to ignore, specify a list of groups separated by spaces. + + bundle config set --local without test + bundle config set --local without development test + +Also, calling `Bundler.setup` with no parameters, or calling `require "bundler/setup"` +will setup all groups except for the ones you excluded via `--without` (since they +are not available). + +Note that on `bundle install`, bundler downloads and evaluates all gems, in order to +create a single canonical list of all of the required gems and their dependencies. +This means that you cannot list different versions of the same gems in different +groups. For more details, see [Understanding Bundler](https://bundler.io/rationale.html). + +### PLATFORMS + +If a gem should only be used in a particular platform or set of platforms, you can +specify them. Platforms are essentially identical to groups, except that you do not +need to use the `--without` install-time flag to exclude groups of gems for other +platforms. + +There are a number of `Gemfile` platforms: + + * `ruby`: + C Ruby (MRI), Rubinius, or TruffleRuby, but not Windows + * `mri`: + C Ruby (MRI) only, but not Windows + * `windows`: + Windows C Ruby (MRI), including RubyInstaller 32-bit and 64-bit versions + * `mswin`: + Windows C Ruby (MRI), including RubyInstaller 32-bit versions + * `mswin64`: + Windows C Ruby (MRI), including RubyInstaller 64-bit versions + * `rbx`: + Rubinius + * `jruby`: + JRuby + * `truffleruby`: + TruffleRuby + +On platforms `ruby`, `mri`, `mswin`, `mswin64`, and `windows`, you may +additionally specify a version by appending the major and minor version numbers +without a delimiter. For example, to specify that a gem should only be used on +platform `ruby` version 3.1, use: + + ruby_31 + +As with groups (above), you may specify one or more platforms: + + gem "weakling", platforms: :jruby + gem "ruby-debug", platforms: :mri_31 + gem "nokogiri", platforms: [:windows_31, :jruby] + +All operations involving groups ([`bundle install`](bundle-install.1.html), `Bundler.setup`, +`Bundler.require`) behave exactly the same as if any groups not +matching the current platform were explicitly excluded. + +### FORCE_RUBY_PLATFORM + +If you always want the pure ruby variant of a gem to be chosen over platform +specific variants, you can use the `force_ruby_platform` option: + + gem "ffi", force_ruby_platform: true + +This can be handy (assuming the pure ruby variant works fine) when: + +* You're having issues with the platform specific variant. +* The platform specific variant does not yet support a newer ruby (and thus has + a `required_ruby_version` upper bound), but you still want your Gemfile{.lock} + files to resolve under that ruby. + +### SOURCE + +You can select an alternate RubyGems repository for a gem using the ':source' +option. + + gem "some_internal_gem", source: "https://gems.example.com" + +This forces the gem to be loaded from this source and ignores the global source +declared at the top level of the file. If the gem does not exist in this source, +it will not be installed. + +Bundler will search for child dependencies of this gem by first looking in the +source selected for the parent, but if they are not found there, it will fall +back on the global source. + +**Note about a behavior of the feature deprecated in Bundler 1.13**: +Selecting a specific source repository this way also suppresses the ambiguous +gem warning described above in [GLOBAL SOURCE](#GLOBAL-SOURCE). + +Using the `:source` option for an individual gem will also make that source +available as a possible global source for any other gems which do not specify +explicit sources. Thus, when adding gems with explicit sources, it is +recommended that you also ensure all other gems in the Gemfile are using +explicit sources. + +### GIT + +If necessary, you can specify that a gem is located at a particular +git repository using the `:git` parameter. The repository can be accessed via +several protocols: + + * `HTTP(S)`: + gem "rails", git: "https://github.com/rails/rails.git" + * `SSH`: + gem "rails", git: "git@github.com:rails/rails.git" + * `git`: + gem "rails", git: "git://github.com/rails/rails.git" + +If using SSH, the user that you use to run `bundle install` `MUST` have the +appropriate keys available in their `$HOME/.ssh`. + +`NOTE`: `http://` and `git://` URLs should be avoided if at all possible. These +protocols are unauthenticated, so a man-in-the-middle attacker can deliver +malicious code and compromise your system. HTTPS and SSH are strongly +preferred. + +The `group`, `platforms`, and `require` options are available and behave +exactly the same as they would for a normal gem. + +A git repository `SHOULD` have at least one file, at the root of the +directory containing the gem, with the extension `.gemspec`. This file +`MUST` contain a valid gem specification, as expected by the `gem build` +command. + +If a git repository does not have a `.gemspec`, bundler will attempt to +create one, but it will not contain any dependencies, executables, or +C extension compilation instructions. As a result, it may fail to properly +integrate into your application. + +If a git repository does have a `.gemspec` for the gem you attached it +to, a version specifier, if provided, means that the git repository is +only valid if the `.gemspec` specifies a version matching the version +specifier. If not, bundler will print a warning. + + gem "rails", "2.3.8", git: "https://github.com/rails/rails.git" + # bundle install will fail, because the .gemspec in the rails + # repository's master branch specifies version 3.0.0 + +If a git repository does `not` have a `.gemspec` for the gem you attached +it to, a version specifier `MUST` be provided. Bundler will use this +version in the simple `.gemspec` it creates. + +Git repositories support a number of additional options. + + * `branch`, `tag`, and `ref`: + You `MUST` only specify at most one of these options. The default + is `branch: "master"`. For example: + + gem "rails", git: "https://github.com/rails/rails.git", branch: "5-0-stable" + + gem "rails", git: "https://github.com/rails/rails.git", tag: "v5.0.0" + + gem "rails", git: "https://github.com/rails/rails.git", ref: "4aded" + + * `submodules`: + For reference, a [git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules) + lets you have another git repository within a subfolder of your repository. + Specify `submodules: true` to cause bundler to expand any + submodules included in the git repository + +If a git repository contains multiple `.gemspecs`, each `.gemspec` +represents a gem located at the same place in the file system as +the `.gemspec`. + + |~rails [git root] + | |-rails.gemspec [rails gem located here] + |~actionpack + | |-actionpack.gemspec [actionpack gem located here] + |~activesupport + | |-activesupport.gemspec [activesupport gem located here] + |... + +To install a gem located in a git repository, bundler changes to +the directory containing the gemspec, runs `gem build name.gemspec` +and then installs the resulting gem. The `gem build` command, +which comes standard with Rubygems, evaluates the `.gemspec` in +the context of the directory in which it is located. + +### GIT SOURCE + +A custom git source can be defined via the `git_source` method. Provide the source's name +as an argument, and a block which receives a single argument and interpolates it into a +string to return the full repo address: + + git_source(:stash){ |repo_name| "https://stash.corp.acme.pl/#{repo_name}.git" } + gem 'rails', stash: 'forks/rails' + +In addition, if you wish to choose a specific branch: + + gem "rails", stash: "forks/rails", branch: "branch_name" + +### GITHUB + +`NOTE`: This shorthand should be avoided until Bundler 2.0, since it +currently expands to an insecure `git://` URL. This allows a +man-in-the-middle attacker to compromise your system. + +If the git repository you want to use is hosted on GitHub and is public, you can use the +:github shorthand to specify the github username and repository name (without the +trailing ".git"), separated by a slash. If both the username and repository name are the +same, you can omit one. + + gem "rails", github: "rails/rails" + gem "rails", github: "rails" + +Are both equivalent to + + gem "rails", git: "https://github.com/rails/rails.git" + +Since the `github` method is a specialization of `git_source`, it accepts a `:branch` named argument. + +You can also directly pass a pull request URL: + + gem "rails", github: "https://github.com/rails/rails/pull/43753" + +Which is equivalent to: + + gem "rails", github: "rails/rails", branch: "refs/pull/43753/head" + +### GIST + +If the git repository you want to use is hosted as a GitHub Gist and is public, you can use +the :gist shorthand to specify the gist identifier (without the trailing ".git"). + + gem "the_hatch", gist: "4815162342" + +Is equivalent to: + + gem "the_hatch", git: "https://gist.github.com/4815162342.git" + +Since the `gist` method is a specialization of `git_source`, it accepts a `:branch` named argument. + +### BITBUCKET + +If the git repository you want to use is hosted on Bitbucket and is public, you can use the +:bitbucket shorthand to specify the bitbucket username and repository name (without the +trailing ".git"), separated by a slash. If both the username and repository name are the +same, you can omit one. + + gem "rails", bitbucket: "rails/rails" + gem "rails", bitbucket: "rails" + +Are both equivalent to + + gem "rails", git: "https://rails@bitbucket.org/rails/rails.git" + +Since the `bitbucket` method is a specialization of `git_source`, it accepts a `:branch` named argument. + +### PATH + +You can specify that a gem is located in a particular location +on the file system. Relative paths are resolved relative to the +directory containing the `Gemfile`. + +Similar to the semantics of the `:git` option, the `:path` +option requires that the directory in question either contains +a `.gemspec` for the gem, or that you specify an explicit +version that bundler should use. + +Unlike `:git`, bundler does not compile C extensions for +gems specified as paths. + + gem "rails", path: "vendor/rails" + +If you would like to use multiple local gems directly from the filesystem, you can set a global `path` option to the path containing the gem's files. This will automatically load gemspec files from subdirectories. + + path 'components' do + gem 'admin_ui' + gem 'public_ui' + end + +## BLOCK FORM OF SOURCE, GIT, PATH, GROUP and PLATFORMS + +The `:source`, `:git`, `:path`, `:group`, and `:platforms` options may be +applied to a group of gems by using block form. + + source "https://gems.example.com" do + gem "some_internal_gem" + gem "another_internal_gem" + end + + git "https://github.com/rails/rails.git" do + gem "activesupport" + gem "actionpack" + end + + platforms :ruby do + gem "ruby-debug" + gem "sqlite3" + end + + group :development, optional: true do + gem "wirble" + gem "faker" + end + +In the case of the group block form the :optional option can be given +to prevent a group from being installed unless listed in the `--with` +option given to the `bundle install` command. + +In the case of the `git` block form, the `:ref`, `:branch`, `:tag`, +and `:submodules` options may be passed to the `git` method, and +all gems in the block will inherit those options. + +The presence of a `source` block in a Gemfile also makes that source +available as a possible global source for any other gems which do not specify +explicit sources. Thus, when defining source blocks, it is +recommended that you also ensure all other gems in the Gemfile are using +explicit sources, either via source blocks or `:source` directives on +individual gems. + +## INSTALL_IF + +The `install_if` method allows gems to be installed based on a proc or lambda. +This is especially useful for optional gems that can only be used if certain +software is installed or some other conditions are met. + + install_if -> { RUBY_PLATFORM =~ /darwin/ } do + gem "pasteboard" + end + +## GEMSPEC + +The [`.gemspec`](http://guides.rubygems.org/specification-reference/) file is where + you provide metadata about your gem to Rubygems. Some required Gemspec + attributes include the name, description, and homepage of your gem. This is + also where you specify the dependencies your gem needs to run. + +If you wish to use Bundler to help install dependencies for a gem while it is +being developed, use the `gemspec` method to pull in the dependencies listed in +the `.gemspec` file. + +The `gemspec` method adds any runtime dependencies as gem requirements in the +default group. It also adds development dependencies as gem requirements in the +`development` group. Finally, it adds a gem requirement on your project (`path: +'.'`). In conjunction with `Bundler.setup`, this allows you to require project +files in your test code as you would if the project were installed as a gem; you +need not manipulate the load path manually or require project files via relative +paths. + +The `gemspec` method supports optional `:path`, `:glob`, `:name`, and `:development_group` +options, which control where bundler looks for the `.gemspec`, the glob it uses to look +for the gemspec (defaults to: "{,*,*/*}.gemspec"), what named `.gemspec` it uses +(if more than one is present), and which group development dependencies are included in. + +When a `gemspec` dependency encounters version conflicts during resolution, the +local version under development will always be selected -- even if there are +remote versions that better match other requirements for the `gemspec` gem. + +## SOURCE PRIORITY + +When attempting to locate a gem to satisfy a gem requirement, +bundler uses the following priority order: + + 1. The source explicitly attached to the gem (using `:source`, `:path`, or + `:git`) + 2. For implicit gems (dependencies of explicit gems), any source, git, or path + repository declared on the parent. This results in bundler prioritizing the + ActiveSupport gem from the Rails git repository over ones from + `rubygems.org` + 3. If neither of the above conditions are met, the global source will be used. + If multiple global sources are specified, they will be prioritized from + last to first, but this is deprecated since Bundler 1.13, so Bundler prints + a warning and will abort with an error in the future. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/match_metadata.rb b/games/FNaFB2/Ruby/stdlib/bundler/match_metadata.rb new file mode 100644 index 0000000..499036c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/match_metadata.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Bundler + module MatchMetadata + def matches_current_ruby? + @required_ruby_version.satisfied_by?(Gem.ruby_version) + end + + def matches_current_rubygems? + @required_rubygems_version.satisfied_by?(Gem.rubygems_version) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/match_platform.rb b/games/FNaFB2/Ruby/stdlib/bundler/match_platform.rb new file mode 100644 index 0000000..7f7e822 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/match_platform.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require_relative "gem_helpers" + +module Bundler + module MatchPlatform + include GemHelpers + + def match_platform(p) + MatchPlatform.platforms_match?(platform, p) + end + + def self.platforms_match?(gemspec_platform, local_platform) + return true if gemspec_platform.nil? + return true if Gem::Platform::RUBY == gemspec_platform + return true if local_platform == gemspec_platform + gemspec_platform = Gem::Platform.new(gemspec_platform) + return true if gemspec_platform === local_platform + + false + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/match_remote_metadata.rb b/games/FNaFB2/Ruby/stdlib/bundler/match_remote_metadata.rb new file mode 100644 index 0000000..5e46d52 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/match_remote_metadata.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Bundler + module FetchMetadata + # A fallback is included because the original version of the specification + # API didn't include that field, so some marshalled specs in the index have it + # set to +nil+. + def matches_current_ruby? + @required_ruby_version ||= _remote_specification.required_ruby_version || Gem::Requirement.default + + super + end + + def matches_current_rubygems? + # A fallback is included because the original version of the specification + # API didn't include that field, so some marshalled specs in the index have it + # set to +nil+. + @required_rubygems_version ||= _remote_specification.required_rubygems_version || Gem::Requirement.default + + super + end + end + + module MatchRemoteMetadata + include MatchMetadata + + prepend FetchMetadata + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/mirror.rb b/games/FNaFB2/Ruby/stdlib/bundler/mirror.rb new file mode 100644 index 0000000..a63b45b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/mirror.rb @@ -0,0 +1,223 @@ +# frozen_string_literal: true + +require "socket" + +module Bundler + class Settings + # Class used to build the mirror set and then find a mirror for a given URI + # + # @param prober [Prober object, nil] by default a TCPSocketProbe, this object + # will be used to probe the mirror address to validate that the mirror replies. + class Mirrors + def initialize(prober = nil) + @all = Mirror.new + @prober = prober || TCPSocketProbe.new + @mirrors = {} + end + + # Returns a mirror for the given uri. + # + # Depending on the uri having a valid mirror or not, it may be a + # mirror that points to the provided uri + def for(uri) + if @all.validate!(@prober).valid? + @all + else + fetch_valid_mirror_for(Settings.normalize_uri(uri)) + end + end + + def each + @mirrors.each do |k, v| + yield k, v.uri.to_s + end + end + + def parse(key, value) + config = MirrorConfig.new(key, value) + mirror = if config.all? + @all + else + @mirrors[config.uri] ||= Mirror.new + end + config.update_mirror(mirror) + end + + private + + def fetch_valid_mirror_for(uri) + downcased = uri.to_s.downcase + mirror = @mirrors[downcased] || @mirrors[Bundler::URI(downcased).host] || Mirror.new(uri) + mirror.validate!(@prober) + mirror = Mirror.new(uri) unless mirror.valid? + mirror + end + end + + # A mirror + # + # Contains both the uri that should be used as a mirror and the + # fallback timeout which will be used for probing if the mirror + # replies on time or not. + class Mirror + DEFAULT_FALLBACK_TIMEOUT = 0.1 + + attr_reader :uri, :fallback_timeout + + def initialize(uri = nil, fallback_timeout = 0) + self.uri = uri + self.fallback_timeout = fallback_timeout + @valid = nil + end + + def uri=(uri) + @uri = if uri.nil? + nil + else + Bundler::URI(uri.to_s) + end + @valid = nil + end + + def fallback_timeout=(timeout) + case timeout + when true, "true" + @fallback_timeout = DEFAULT_FALLBACK_TIMEOUT + when false, "false" + @fallback_timeout = 0 + else + @fallback_timeout = timeout.to_i + end + @valid = nil + end + + def ==(other) + !other.nil? && uri == other.uri && fallback_timeout == other.fallback_timeout + end + + def valid? + return false if @uri.nil? + return @valid unless @valid.nil? + false + end + + def validate!(probe = nil) + @valid = false if uri.nil? + if @valid.nil? + @valid = fallback_timeout == 0 || (probe || TCPSocketProbe.new).replies?(self) + end + self + end + end + + # Class used to parse one configuration line + # + # Gets the configuration line and the value. + # This object provides a `update_mirror` method + # used to setup the given mirror value. + class MirrorConfig + attr_accessor :uri, :value + + def initialize(config_line, value) + uri, fallback = + config_line.match(%r{\Amirror\.(all|.+?)(\.fallback_timeout)?\/?\z}).captures + @fallback = !fallback.nil? + @all = false + if uri == "all" + @all = true + else + @uri = Bundler::URI(uri).absolute? ? Settings.normalize_uri(uri) : uri + end + @value = value + end + + def all? + @all + end + + def update_mirror(mirror) + if @fallback + mirror.fallback_timeout = @value + else + mirror.uri = Settings.normalize_uri(@value) + end + end + end + + # Class used for probing TCP availability for a given mirror. + class TCPSocketProbe + def replies?(mirror) + MirrorSockets.new(mirror).any? do |socket, address, timeout| + begin + socket.connect_nonblock(address) + rescue Errno::EINPROGRESS + wait_for_writtable_socket(socket, address, timeout) + rescue RuntimeError # Connection failed somehow, again + false + end + end + end + + private + + def wait_for_writtable_socket(socket, address, timeout) + if IO.select(nil, [socket], nil, timeout) + probe_writtable_socket(socket, address) + else # TCP Handshake timed out, or there is something dropping packets + false + end + end + + def probe_writtable_socket(socket, address) + socket.connect_nonblock(address) + rescue Errno::EISCONN + true + rescue StandardError # Connection failed + false + end + end + end + + # Class used to build the list of sockets that correspond to + # a given mirror. + # + # One mirror may correspond to many different addresses, both + # because of it having many dns entries or because + # the network interface is both ipv4 and ipv5 + class MirrorSockets + def initialize(mirror) + @timeout = mirror.fallback_timeout + @addresses = Socket.getaddrinfo(mirror.uri.host, mirror.uri.port).map do |address| + SocketAddress.new(address[0], address[3], address[1]) + end + end + + def any? + @addresses.any? do |address| + socket = Socket.new(Socket.const_get(address.type), Socket::SOCK_STREAM, 0) + socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) + value = yield socket, address.to_socket_address, @timeout + socket.close unless socket.closed? + value + end + end + end + + # Socket address builder. + # + # Given a socket type, a host and a port, + # provides a method to build sockaddr string + class SocketAddress + attr_reader :type, :host, :port + + def initialize(type, host, port) + @type = type + @host = host + @port = port + end + + def to_socket_address + Socket.pack_sockaddr_in(@port, @host) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/plugin.rb b/games/FNaFB2/Ruby/stdlib/bundler/plugin.rb new file mode 100644 index 0000000..26458bd --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/plugin.rb @@ -0,0 +1,352 @@ +# frozen_string_literal: true + +require_relative "plugin/api" + +module Bundler + module Plugin + autoload :DSL, File.expand_path("plugin/dsl", __dir__) + autoload :Events, File.expand_path("plugin/events", __dir__) + autoload :Index, File.expand_path("plugin/index", __dir__) + autoload :Installer, File.expand_path("plugin/installer", __dir__) + autoload :SourceList, File.expand_path("plugin/source_list", __dir__) + + class MalformattedPlugin < PluginError; end + class UndefinedCommandError < PluginError; end + class UnknownSourceError < PluginError; end + class PluginInstallError < PluginError; end + + PLUGIN_FILE_NAME = "plugins.rb".freeze + + module_function + + def reset! + instance_variables.each {|i| remove_instance_variable(i) } + + @sources = {} + @commands = {} + @hooks_by_event = Hash.new {|h, k| h[k] = [] } + @loaded_plugin_names = [] + end + + reset! + + # Installs a new plugin by the given name + # + # @param [Array] names the name of plugin to be installed + # @param [Hash] options various parameters as described in description. + # Refer to cli/plugin for available options + def install(names, options) + raise InvalidOption, "You cannot specify `--branch` and `--ref` at the same time." if options["branch"] && options["ref"] + + specs = Installer.new.install(names, options) + + save_plugins names, specs + rescue PluginError + specs_to_delete = specs.select {|k, _v| names.include?(k) && !index.commands.values.include?(k) } + specs_to_delete.each_value {|spec| Bundler.rm_rf(spec.full_gem_path) } + + raise + end + + # Uninstalls plugins by the given names + # + # @param [Array] names the names of plugins to be uninstalled + def uninstall(names, options) + if names.empty? && !options[:all] + Bundler.ui.error "No plugins to uninstall. Specify at least 1 plugin to uninstall.\n"\ + "Use --all option to uninstall all the installed plugins." + return + end + + names = index.installed_plugins if options[:all] + if names.any? + names.each do |name| + if index.installed?(name) + Bundler.rm_rf(index.plugin_path(name)) + index.unregister_plugin(name) + Bundler.ui.info "Uninstalled plugin #{name}" + else + Bundler.ui.error "Plugin #{name} is not installed \n" + end + end + else + Bundler.ui.info "No plugins installed" + end + end + + # List installed plugins and commands + # + def list + installed_plugins = index.installed_plugins + if installed_plugins.any? + output = String.new + installed_plugins.each do |plugin| + output << "#{plugin}\n" + output << "-----\n" + index.plugin_commands(plugin).each do |command| + output << " #{command}\n" + end + output << "\n" + end + else + output = "No plugins installed" + end + Bundler.ui.info output + end + + # Evaluates the Gemfile with a limited DSL and installs the plugins + # specified by plugin method + # + # @param [Pathname] gemfile path + # @param [Proc] block that can be evaluated for (inline) Gemfile + def gemfile_install(gemfile = nil, &inline) + Bundler.settings.temporary(:frozen => false, :deployment => false) do + builder = DSL.new + if block_given? + builder.instance_eval(&inline) + else + builder.eval_gemfile(gemfile) + end + builder.check_primary_source_safety + definition = builder.to_definition(nil, true) + + return if definition.dependencies.empty? + + plugins = definition.dependencies.map(&:name).reject {|p| index.installed? p } + installed_specs = Installer.new.install_definition(definition) + + save_plugins plugins, installed_specs, builder.inferred_plugins + end + rescue RuntimeError => e + unless e.is_a?(GemfileError) + Bundler.ui.error "Failed to install plugin: #{e.message}\n #{e.backtrace[0]}" + end + raise + end + + # The index object used to store the details about the plugin + def index + @index ||= Index.new + end + + # The directory root for all plugin related data + # + # If run in an app, points to local root, in app_config_path + # Otherwise, points to global root, in Bundler.user_bundle_path("plugin") + def root + @root ||= if SharedHelpers.in_bundle? + local_root + else + global_root + end + end + + def local_root + Bundler.app_config_path.join("plugin") + end + + # The global directory root for all plugin related data + def global_root + Bundler.user_bundle_path("plugin") + end + + # The cache directory for plugin stuffs + def cache + @cache ||= root.join("cache") + end + + # To be called via the API to register to handle a command + def add_command(command, cls) + @commands[command] = cls + end + + # Checks if any plugin handles the command + def command?(command) + !index.command_plugin(command).nil? + end + + # To be called from Cli class to pass the command and argument to + # appropriate plugin class + def exec_command(command, args) + raise UndefinedCommandError, "Command `#{command}` not found" unless command? command + + load_plugin index.command_plugin(command) unless @commands.key? command + + @commands[command].new.exec(command, args) + end + + # To be called via the API to register to handle a source plugin + def add_source(source, cls) + @sources[source] = cls + end + + # Checks if any plugin declares the source + def source?(name) + !index.source_plugin(name.to_s).nil? + end + + # @return [Class] that handles the source. The class includes API::Source + def source(name) + raise UnknownSourceError, "Source #{name} not found" unless source? name + + load_plugin(index.source_plugin(name)) unless @sources.key? name + + @sources[name] + end + + # @param [Hash] The options that are present in the lock file + # @return [API::Source] the instance of the class that handles the source + # type passed in locked_opts + def source_from_lock(locked_opts) + src = source(locked_opts["type"]) + + src.new(locked_opts.merge("uri" => locked_opts["remote"])) + end + + # To be called via the API to register a hooks and corresponding block that + # will be called to handle the hook + def add_hook(event, &block) + unless Events.defined_event?(event) + raise ArgumentError, "Event '#{event}' not defined in Bundler::Plugin::Events" + end + @hooks_by_event[event.to_s] << block + end + + # Runs all the hooks that are registered for the passed event + # + # It passes the passed arguments and block to the block registered with + # the api. + # + # @param [String] event + def hook(event, *args, &arg_blk) + return unless Bundler.feature_flag.plugins? + unless Events.defined_event?(event) + raise ArgumentError, "Event '#{event}' not defined in Bundler::Plugin::Events" + end + + plugins = index.hook_plugins(event) + return unless plugins.any? + + (plugins - @loaded_plugin_names).each {|name| load_plugin(name) } + + @hooks_by_event[event].each {|blk| blk.call(*args, &arg_blk) } + end + + # currently only intended for specs + # + # @return [String, nil] installed path + def installed?(plugin) + Index.new.installed?(plugin) + end + + # Post installation processing and registering with index + # + # @param [Array] plugins list to be installed + # @param [Hash] specs of plugins mapped to installation path (currently they + # contain all the installed specs, including plugins) + # @param [Array] names of inferred source plugins that can be ignored + def save_plugins(plugins, specs, optional_plugins = []) + plugins.each do |name| + next if index.installed?(name) + + spec = specs[name] + + save_plugin(name, spec, optional_plugins.include?(name)) + end + end + + # Checks if the gem is good to be a plugin + # + # At present it only checks whether it contains plugins.rb file + # + # @param [Pathname] plugin_path the path plugin is installed at + # @raise [MalformattedPlugin] if plugins.rb file is not found + def validate_plugin!(plugin_path) + plugin_file = plugin_path.join(PLUGIN_FILE_NAME) + raise MalformattedPlugin, "#{PLUGIN_FILE_NAME} was not found in the plugin." unless plugin_file.file? + end + + # Validates and registers a plugin. + # + # @param [String] name the name of the plugin + # @param [Specification] spec of installed plugin + # @param [Boolean] optional_plugin, removed if there is conflict with any + # other plugin (used for default source plugins) + # + # @raise [PluginInstallError] if validation or registration raises any error + def save_plugin(name, spec, optional_plugin = false) + validate_plugin! Pathname.new(spec.full_gem_path) + installed = register_plugin(name, spec, optional_plugin) + Bundler.ui.info "Installed plugin #{name}" if installed + rescue PluginError => e + raise PluginInstallError, "Failed to install plugin `#{spec.name}`, due to #{e.class} (#{e.message})" + end + + # Runs the plugins.rb file in an isolated namespace, records the plugin + # actions it registers for and then passes the data to index to be stored. + # + # @param [String] name the name of the plugin + # @param [Specification] spec of installed plugin + # @param [Boolean] optional_plugin, removed if there is conflict with any + # other plugin (used for default source plugins) + # + # @raise [MalformattedPlugin] if plugins.rb raises any error + def register_plugin(name, spec, optional_plugin = false) + commands = @commands + sources = @sources + hooks = @hooks_by_event + + @commands = {} + @sources = {} + @hooks_by_event = Hash.new {|h, k| h[k] = [] } + + load_paths = spec.load_paths + Bundler.rubygems.add_to_load_path(load_paths) + path = Pathname.new spec.full_gem_path + + begin + load path.join(PLUGIN_FILE_NAME), true + rescue StandardError => e + raise MalformattedPlugin, "#{e.class}: #{e.message}" + end + + if optional_plugin && @sources.keys.any? {|s| source? s } + Bundler.rm_rf(path) + false + else + index.register_plugin(name, path.to_s, load_paths, @commands.keys, + @sources.keys, @hooks_by_event.keys) + true + end + ensure + @commands = commands + @sources = sources + @hooks_by_event = hooks + end + + # Executes the plugins.rb file + # + # @param [String] name of the plugin + def load_plugin(name) + return unless name && !name.empty? + + # Need to ensure before this that plugin root where the rest of gems + # are installed to be on load path to support plugin deps. Currently not + # done to avoid conflicts + path = index.plugin_path(name) + + Bundler.rubygems.add_to_load_path(index.load_paths(name)) + + load path.join(PLUGIN_FILE_NAME) + + @loaded_plugin_names << name + rescue RuntimeError => e + Bundler.ui.error "Failed loading plugin #{name}: #{e.message}" + raise + end + + class << self + private :load_plugin, :register_plugin, :save_plugins, :validate_plugin! + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/plugin/api.rb b/games/FNaFB2/Ruby/stdlib/bundler/plugin/api.rb new file mode 100644 index 0000000..ee2bffe --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/plugin/api.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +module Bundler + # This is the interfacing class represents the API that we intend to provide + # the plugins to use. + # + # For plugins to be independent of the Bundler internals they shall limit their + # interactions to methods of this class only. This will save them from breaking + # when some internal change. + # + # Currently we are delegating the methods defined in Bundler class to + # itself. So, this class acts as a buffer. + # + # If there is some change in the Bundler class that is incompatible to its + # previous behavior or if otherwise desired, we can reimplement(or implement) + # the method to preserve compatibility. + # + # To use this, either the class can inherit this class or use it directly. + # For example of both types of use, refer the file `spec/plugins/command.rb` + # + # To use it without inheriting, you will have to create an object of this + # to use the functions (except for declaration functions like command, source, + # and hooks). + module Plugin + class API + autoload :Source, File.expand_path("api/source", __dir__) + + # The plugins should declare that they handle a command through this helper. + # + # @param [String] command being handled by them + # @param [Class] (optional) class that handles the command. If not + # provided, the `self` class will be used. + def self.command(command, cls = self) + Plugin.add_command command, cls + end + + # The plugins should declare that they provide a installation source + # through this helper. + # + # @param [String] the source type they provide + # @param [Class] (optional) class that handles the source. If not + # provided, the `self` class will be used. + def self.source(source, cls = self) + cls.send :include, Bundler::Plugin::API::Source + Plugin.add_source source, cls + end + + def self.hook(event, &block) + Plugin.add_hook(event, &block) + end + + # The cache dir to be used by the plugins for storage + # + # @return [Pathname] path of the cache dir + def cache_dir + Plugin.cache.join("plugins") + end + + # A tmp dir to be used by plugins + # Accepts names that get concatenated as suffix + # + # @return [Pathname] object for the new directory created + def tmp(*names) + Bundler.tmp(["plugin", *names].join("-")) + end + + def method_missing(name, *args, &blk) + return Bundler.send(name, *args, &blk) if Bundler.respond_to?(name) + + return SharedHelpers.send(name, *args, &blk) if SharedHelpers.respond_to?(name) + + super + end + + def respond_to_missing?(name, include_private = false) + SharedHelpers.respond_to?(name, include_private) || + Bundler.respond_to?(name, include_private) || super + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/plugin/api/source.rb b/games/FNaFB2/Ruby/stdlib/bundler/plugin/api/source.rb new file mode 100644 index 0000000..67c45bd --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/plugin/api/source.rb @@ -0,0 +1,320 @@ +# frozen_string_literal: true + +module Bundler + module Plugin + class API + # This class provides the base to build source plugins + # All the method here are required to build a source plugin (except + # `uri_hash`, `gem_install_dir`; they are helpers). + # + # Defaults for methods, where ever possible are provided which is + # expected to work. But, all source plugins have to override + # `fetch_gemspec_files` and `install`. Defaults are also not provided for + # `remote!`, `cache!` and `unlock!`. + # + # The defaults shall work for most situations but nevertheless they can + # be (preferably should be) overridden as per the plugins' needs safely + # (as long as they behave as expected). + # On overriding `initialize` you should call super first. + # + # If required plugin should override `hash`, `==` and `eql?` methods to be + # able to match objects representing same sources, but may be created in + # different situation (like form gemfile and lockfile). The default ones + # checks only for class and uri, but elaborate source plugins may need + # more comparisons (e.g. git checking on branch or tag). + # + # @!attribute [r] uri + # @return [String] the remote specified with `source` block in Gemfile + # + # @!attribute [r] options + # @return [String] options passed during initialization (either from + # lockfile or Gemfile) + # + # @!attribute [r] name + # @return [String] name that can be used to uniquely identify a source + # + # @!attribute [rw] dependency_names + # @return [Array] Names of dependencies that the source should + # try to resolve. It is not necessary to use this list internally. This + # is present to be compatible with `Definition` and is used by + # rubygems source. + module Source + attr_reader :uri, :options, :name + attr_accessor :dependency_names + + def initialize(opts) + @options = opts + @dependency_names = [] + @uri = opts["uri"] + @type = opts["type"] + @name = opts["name"] || "#{@type} at #{@uri}" + end + + # This is used by the default `spec` method to constructs the + # Specification objects for the gems and versions that can be installed + # by this source plugin. + # + # Note: If the spec method is overridden, this function is not necessary + # + # @return [Array] paths of the gemspec files for gems that can + # be installed + def fetch_gemspec_files + [] + end + + # Options to be saved in the lockfile so that the source plugin is able + # to check out same version of gem later. + # + # There options are passed when the source plugin is created from the + # lock file. + # + # @return [Hash] + def options_to_lock + {} + end + + # Install the gem specified by the spec at appropriate path. + # `install_path` provides a sufficient default, if the source can only + # satisfy one gem, but is not binding. + # + # @return [String] post installation message (if any) + def install(spec, opts) + raise MalformattedPlugin, "Source plugins need to override the install method." + end + + # It builds extensions, generates bins and installs them for the spec + # provided. + # + # It depends on `spec.loaded_from` to get full_gem_path. The source + # plugins should set that. + # + # It should be called in `install` after the plugin is done placing the + # gem at correct install location. + # + # It also runs Gem hooks `pre_install`, `post_build` and `post_install` + # + # Note: Do not override if you don't know what you are doing. + def post_install(spec, disable_exts = false) + opts = { :env_shebang => false, :disable_extensions => disable_exts } + installer = Bundler::Source::Path::Installer.new(spec, opts) + installer.post_install + end + + # A default installation path to install a single gem. If the source + # servers multiple gems, it's not of much use and the source should one + # of its own. + def install_path + @install_path ||= + begin + base_name = File.basename(Bundler::URI.parse(uri).normalize.path) + + gem_install_dir.join("#{base_name}-#{uri_hash[0..11]}") + end + end + + # Parses the gemspec files to find the specs for the gems that can be + # satisfied by the source. + # + # Few important points to keep in mind: + # - If the gems are not installed then it shall return specs for all + # the gems it can satisfy + # - If gem is installed (that is to be detected by the plugin itself) + # then it shall return at least the specs that are installed. + # - The `loaded_from` for each of the specs shall be correct (it is + # used to find the load path) + # + # @return [Bundler::Index] index containing the specs + def specs + files = fetch_gemspec_files + + Bundler::Index.build do |index| + files.each do |file| + next unless spec = Bundler.load_gemspec(file) + Bundler.rubygems.set_installed_by_version(spec) + + spec.source = self + Bundler.rubygems.validate(spec) + + index << spec + end + end + end + + # Set internal representation to fetch the gems/specs locally. + # + # When this is called, the source should try to fetch the specs and + # install from the local system. + def local! + end + + # Set internal representation to fetch the gems/specs from remote. + # + # When this is called, the source should try to fetch the specs and + # install from remote path. + def remote! + end + + # Set internal representation to fetch the gems/specs from app cache. + # + # When this is called, the source should try to fetch the specs and + # install from the path provided by `app_cache_path`. + def cached! + end + + # This is called to update the spec and installation. + # + # If the source plugin is loaded from lockfile or otherwise, it shall + # refresh the cache/specs (e.g. git sources can make a fresh clone). + def unlock! + end + + # Name of directory where plugin the is expected to cache the gems when + # #cache is called. + # + # Also this name is matched against the directories in cache for pruning + # + # This is used by `app_cache_path` + def app_cache_dirname + base_name = File.basename(Bundler::URI.parse(uri).normalize.path) + "#{base_name}-#{uri_hash}" + end + + # This method is called while caching to save copy of the gems that the + # source can resolve to path provided by `app_cache_app`so that they can + # be reinstalled from the cache without querying the remote (i.e. an + # alternative to remote) + # + # This is stored with the app and source plugins should try to provide + # specs and install only from this cache when `cached!` is called. + # + # This cache is different from the internal caching that can be done + # at sub paths of `cache_path` (from API). This can be though as caching + # by bundler. + def cache(spec, custom_path = nil) + new_cache_path = app_cache_path(custom_path) + + FileUtils.rm_rf(new_cache_path) + FileUtils.cp_r(install_path, new_cache_path) + FileUtils.touch(app_cache_path.join(".bundlecache")) + end + + # This shall check if two source object represent the same source. + # + # The comparison shall take place only on the attribute that can be + # inferred from the options passed from Gemfile and not on attributes + # that are used to pin down the gem to specific version (e.g. Git + # sources should compare on branch and tag but not on commit hash) + # + # The sources objects are constructed from Gemfile as well as from + # lockfile. To converge the sources, it is necessary that they match. + # + # The same applies for `eql?` and `hash` + def ==(other) + other.is_a?(self.class) && uri == other.uri + end + + # When overriding `eql?` please preserve the behaviour as mentioned in + # docstring for `==` method. + alias_method :eql?, :== + + # When overriding `hash` please preserve the behaviour as mentioned in + # docstring for `==` method, i.e. two methods equal by above comparison + # should have same hash. + def hash + [self.class, uri].hash + end + + # A helper method, not necessary if not used internally. + def installed? + File.directory?(install_path) + end + + # The full path where the plugin should cache the gem so that it can be + # installed latter. + # + # Note: Do not override if you don't know what you are doing. + def app_cache_path(custom_path = nil) + @app_cache_path ||= Bundler.app_cache(custom_path).join(app_cache_dirname) + end + + # Used by definition. + # + # Note: Do not override if you don't know what you are doing. + def unmet_deps + specs.unmet_dependency_names + end + + # Used by definition. + # + # Note: Do not override if you don't know what you are doing. + def spec_names + specs.spec_names + end + + # Used by definition. + # + # Note: Do not override if you don't know what you are doing. + def add_dependency_names(names) + @dependencies |= Array(names) + end + + # NOTE: Do not override if you don't know what you are doing. + def can_lock?(spec) + spec.source == self + end + + # Generates the content to be entered into the lockfile. + # Saves type and remote and also calls to `options_to_lock`. + # + # Plugin should use `options_to_lock` to save information in lockfile + # and not override this. + # + # Note: Do not override if you don't know what you are doing. + def to_lock + out = String.new("#{LockfileParser::PLUGIN}\n") + out << " remote: #{@uri}\n" + out << " type: #{@type}\n" + options_to_lock.each do |opt, value| + out << " #{opt}: #{value}\n" + end + out << " specs:\n" + end + + def to_s + "plugin source for #{@type} with uri #{@uri}" + end + alias_method :identifier, :to_s + + # NOTE: Do not override if you don't know what you are doing. + def include?(other) + other == self + end + + def uri_hash + SharedHelpers.digest(:SHA1).hexdigest(uri) + end + + # NOTE: Do not override if you don't know what you are doing. + def gem_install_dir + Bundler.install_path + end + + # It is used to obtain the full_gem_path. + # + # spec's loaded_from path is expanded against this to get full_gem_path + # + # Note: Do not override if you don't know what you are doing. + def root + Bundler.root + end + + # @private + # This API on source might not be stable, and for now we expect plugins + # to download all specs in `#specs`, so we implement the method for + # compatibility purposes and leave it undocumented (and don't support) + # overriding it) + def double_check_for(*); end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/plugin/dsl.rb b/games/FNaFB2/Ruby/stdlib/bundler/plugin/dsl.rb new file mode 100644 index 0000000..da751d1 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/plugin/dsl.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module Bundler + module Plugin + # Dsl to parse the Gemfile looking for plugins to install + class DSL < Bundler::Dsl + class PluginGemfileError < PluginError; end + alias_method :_gem, :gem # To use for plugin installation as gem + + # So that we don't have to override all there methods to dummy ones + # explicitly. + # They will be handled by method_missing + [:gemspec, :gem, :install_if, :platforms, :env].each {|m| undef_method m } + + # This lists the plugins that was added automatically and not specified by + # the user. + # + # When we encounter :type attribute with a source block, we add a plugin + # by name bundler-source- to list of plugins to be installed. + # + # These plugins are optional and are not installed when there is conflict + # with any other plugin. + attr_reader :inferred_plugins + + def initialize + super + @sources = Plugin::SourceList.new + @inferred_plugins = [] # The source plugins inferred from :type + end + + def plugin(name, *args) + _gem(name, *args) + end + + def method_missing(name, *args) + raise PluginGemfileError, "Undefined local variable or method `#{name}' for Gemfile" unless Bundler::Dsl.method_defined? name + end + + def source(source, *args, &blk) + options = args.last.is_a?(Hash) ? args.pop.dup : {} + options = normalize_hash(options) + return super unless options.key?("type") + + plugin_name = "bundler-source-#{options["type"]}" + + return if @dependencies.any? {|d| d.name == plugin_name } + + plugin(plugin_name) + @inferred_plugins << plugin_name + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/plugin/events.rb b/games/FNaFB2/Ruby/stdlib/bundler/plugin/events.rb new file mode 100644 index 0000000..bc037d1 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/plugin/events.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module Bundler + module Plugin + module Events + def self.define(const, event) + const = const.to_sym.freeze + if const_defined?(const) && const_get(const) != event + raise ArgumentError, "Attempting to reassign #{const} to a different value" + end + const_set(const, event) unless const_defined?(const) + @events ||= {} + @events[event] = const + end + private_class_method :define + + def self.reset + @events.each_value do |const| + remove_const(const) + end + @events = nil + end + private_class_method :reset + + # Check if an event has been defined + # @param event [String] An event to check + # @return [Boolean] A boolean indicating if the event has been defined + def self.defined_event?(event) + @events ||= {} + @events.key?(event) + end + + # @!parse + # A hook called before each individual gem is installed + # Includes a Bundler::ParallelInstaller::SpecInstallation. + # No state, error, post_install_message will be present as nothing has installed yet + # GEM_BEFORE_INSTALL = "before-install" + define :GEM_BEFORE_INSTALL, "before-install" + + # @!parse + # A hook called after each individual gem is installed + # Includes a Bundler::ParallelInstaller::SpecInstallation. + # - If state is failed, an error will be present. + # - If state is success, a post_install_message may be present. + # GEM_AFTER_INSTALL = "after-install" + define :GEM_AFTER_INSTALL, "after-install" + + # @!parse + # A hook called before any gems install + # Includes an Array of Bundler::Dependency objects + # GEM_BEFORE_INSTALL_ALL = "before-install-all" + define :GEM_BEFORE_INSTALL_ALL, "before-install-all" + + # @!parse + # A hook called after any gems install + # Includes an Array of Bundler::Dependency objects + # GEM_AFTER_INSTALL_ALL = "after-install-all" + define :GEM_AFTER_INSTALL_ALL, "after-install-all" + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/plugin/index.rb b/games/FNaFB2/Ruby/stdlib/bundler/plugin/index.rb new file mode 100644 index 0000000..29d33be --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/plugin/index.rb @@ -0,0 +1,185 @@ +# frozen_string_literal: true + +module Bundler + # Manages which plugins are installed and their sources. This also is supposed to map + # which plugin does what (currently the features are not implemented so this class is + # now a stub class). + module Plugin + class Index + class CommandConflict < PluginError + def initialize(plugin, commands) + msg = "Command(s) `#{commands.join("`, `")}` declared by #{plugin} are already registered." + super msg + end + end + + class SourceConflict < PluginError + def initialize(plugin, sources) + msg = "Source(s) `#{sources.join("`, `")}` declared by #{plugin} are already registered." + super msg + end + end + + attr_reader :commands + + def initialize + @plugin_paths = {} + @commands = {} + @sources = {} + @hooks = {} + @load_paths = {} + + begin + load_index(global_index_file, true) + rescue GenericSystemCallError + # no need to fail when on a read-only FS, for example + nil + end + load_index(local_index_file) if SharedHelpers.in_bundle? + end + + # This function is to be called when a new plugin is installed. This + # function shall add the functions of the plugin to existing maps and also + # the name to source location. + # + # @param [String] name of the plugin to be registered + # @param [String] path where the plugin is installed + # @param [Array] load_paths for the plugin + # @param [Array] commands that are handled by the plugin + # @param [Array] sources that are handled by the plugin + def register_plugin(name, path, load_paths, commands, sources, hooks) + old_commands = @commands.dup + + common = commands & @commands.keys + raise CommandConflict.new(name, common) unless common.empty? + commands.each {|c| @commands[c] = name } + + common = sources & @sources.keys + raise SourceConflict.new(name, common) unless common.empty? + sources.each {|k| @sources[k] = name } + + hooks.each do |event| + event_hooks = (@hooks[event] ||= []) << name + event_hooks.uniq! + end + + @plugin_paths[name] = path + @load_paths[name] = load_paths + save_index + rescue StandardError + @commands = old_commands + raise + end + + def unregister_plugin(name) + @commands.delete_if {|_, v| v == name } + @sources.delete_if {|_, v| v == name } + @hooks.each do |hook, names| + names.delete(name) + @hooks.delete(hook) if names.empty? + end + @plugin_paths.delete(name) + @load_paths.delete(name) + save_index + end + + # Path of default index file + def index_file + Plugin.root.join("index") + end + + # Path where the global index file is stored + def global_index_file + Plugin.global_root.join("index") + end + + # Path where the local index file is stored + def local_index_file + Plugin.local_root.join("index") + end + + def plugin_path(name) + Pathname.new @plugin_paths[name] + end + + def load_paths(name) + @load_paths[name] + end + + # Fetch the name of plugin handling the command + def command_plugin(command) + @commands[command] + end + + def installed?(name) + @plugin_paths[name] + end + + def installed_plugins + @plugin_paths.keys + end + + def plugin_commands(plugin) + @commands.find_all {|_, n| n == plugin }.map(&:first) + end + + def source?(source) + @sources.key? source + end + + def source_plugin(name) + @sources[name] + end + + # Returns the list of plugin names handling the passed event + def hook_plugins(event) + @hooks[event] || [] + end + + private + + # Reads the index file from the directory and initializes the instance + # variables. + # + # It skips the sources if the second param is true + # @param [Pathname] index file path + # @param [Boolean] is the index file global index + def load_index(index_file, global = false) + SharedHelpers.filesystem_access(index_file, :read) do |index_f| + valid_file = index_f && index_f.exist? && !index_f.size.zero? + break unless valid_file + + data = index_f.read + + require_relative "../yaml_serializer" + index = YAMLSerializer.load(data) + + @commands.merge!(index["commands"]) + @hooks.merge!(index["hooks"]) + @load_paths.merge!(index["load_paths"]) + @plugin_paths.merge!(index["plugin_paths"]) + @sources.merge!(index["sources"]) unless global + end + end + + # Should be called when any of the instance variables change. Stores the + # instance variables in YAML format. (The instance variables are supposed + # to be only String key value pairs) + def save_index + index = { + "commands" => @commands, + "hooks" => @hooks, + "load_paths" => @load_paths, + "plugin_paths" => @plugin_paths, + "sources" => @sources, + } + + require_relative "../yaml_serializer" + SharedHelpers.filesystem_access(index_file) do |index_f| + FileUtils.mkdir_p(index_f.dirname) + File.open(index_f, "w") {|f| f.puts YAMLSerializer.dump(index) } + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/plugin/installer.rb b/games/FNaFB2/Ruby/stdlib/bundler/plugin/installer.rb new file mode 100644 index 0000000..81ecafa --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/plugin/installer.rb @@ -0,0 +1,109 @@ +# frozen_string_literal: true + +module Bundler + # Handles the installation of plugin in appropriate directories. + # + # This class is supposed to be wrapper over the existing gem installation infra + # but currently it itself handles everything as the Source's subclasses (e.g. Source::RubyGems) + # are heavily dependent on the Gemfile. + module Plugin + class Installer + autoload :Rubygems, File.expand_path("installer/rubygems", __dir__) + autoload :Git, File.expand_path("installer/git", __dir__) + + def install(names, options) + check_sources_consistency!(options) + + version = options[:version] || [">= 0"] + + if options[:git] + install_git(names, version, options) + elsif options[:local_git] + install_local_git(names, version, options) + else + sources = options[:source] || Gem.sources + install_rubygems(names, version, sources) + end + end + + # Installs the plugin from Definition object created by limited parsing of + # Gemfile searching for plugins to be installed + # + # @param [Definition] definition object + # @return [Hash] map of names to their specs they are installed with + def install_definition(definition) + def definition.lock(*); end + definition.resolve_remotely! + specs = definition.specs + + install_from_specs specs + end + + private + + def check_sources_consistency!(options) + if options.key?(:git) && options.key?(:local_git) + raise InvalidOption, "Remote and local plugin git sources can't be both specified" + end + end + + def install_git(names, version, options) + uri = options.delete(:git) + options["uri"] = uri + + install_all_sources(names, version, options, options[:source]) + end + + def install_local_git(names, version, options) + uri = options.delete(:local_git) + options["uri"] = uri + + install_all_sources(names, version, options, options[:source]) + end + + # Installs the plugin from rubygems source and returns the path where the + # plugin was installed + # + # @param [String] name of the plugin gem to search in the source + # @param [Array] version of the gem to install + # @param [String, Array] source(s) to resolve the gem + # + # @return [Hash] map of names to the specs of plugins installed + def install_rubygems(names, version, sources) + install_all_sources(names, version, nil, sources) + end + + def install_all_sources(names, version, git_source_options, rubygems_source) + source_list = SourceList.new + + source_list.add_git_source(git_source_options) if git_source_options + Array(rubygems_source).each {|remote| source_list.add_global_rubygems_remote(remote) } if rubygems_source + + deps = names.map {|name| Dependency.new name, version } + + Bundler.configure_gem_home_and_path(Plugin.root) + + definition = Definition.new(nil, deps, source_list, true) + install_definition(definition) + end + + # Installs the plugins and deps from the provided specs and returns map of + # gems to their paths + # + # @param specs to install + # + # @return [Hash] map of names to the specs + def install_from_specs(specs) + paths = {} + + specs.each do |spec| + spec.source.install spec + + paths[spec.name] = spec + end + + paths + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/plugin/installer/git.rb b/games/FNaFB2/Ruby/stdlib/bundler/plugin/installer/git.rb new file mode 100644 index 0000000..deec5e9 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/plugin/installer/git.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Bundler + module Plugin + class Installer + class Git < Bundler::Source::Git + def cache_path + @cache_path ||= begin + git_scope = "#{base_name}-#{uri_hash}" + + Plugin.cache.join("bundler", "git", git_scope) + end + end + + def install_path + @install_path ||= begin + git_scope = "#{base_name}-#{shortref_for_path(revision)}" + + Plugin.root.join("bundler", "gems", git_scope) + end + end + + def root + Plugin.root + end + + def generate_bin(spec, disable_extensions = false) + # Need to find a way without code duplication + # For now, we can ignore this + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/plugin/installer/rubygems.rb b/games/FNaFB2/Ruby/stdlib/bundler/plugin/installer/rubygems.rb new file mode 100644 index 0000000..7277234 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/plugin/installer/rubygems.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Bundler + module Plugin + class Installer + class Rubygems < Bundler::Source::Rubygems + private + + def requires_sudo? + false # Will change on implementation of project level plugins + end + + def rubygems_dir + Plugin.root + end + + def cache_path + Plugin.cache + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/plugin/source_list.rb b/games/FNaFB2/Ruby/stdlib/bundler/plugin/source_list.rb new file mode 100644 index 0000000..547661c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/plugin/source_list.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Bundler + # SourceList object to be used while parsing the Gemfile, setting the + # approptiate options to be used with Source classes for plugin installation + module Plugin + class SourceList < Bundler::SourceList + def add_git_source(options = {}) + add_source_to_list Plugin::Installer::Git.new(options), git_sources + end + + def add_rubygems_source(options = {}) + add_source_to_list Plugin::Installer::Rubygems.new(options), @rubygems_sources + end + + def all_sources + path_sources + git_sources + rubygems_sources + [metadata_source] + end + + def default_source + git_sources.first || global_rubygems_source + end + + private + + def rubygems_aggregate_class + Plugin::Installer::Rubygems + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/process_lock.rb b/games/FNaFB2/Ruby/stdlib/bundler/process_lock.rb new file mode 100644 index 0000000..0297f80 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/process_lock.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Bundler + class ProcessLock + def self.lock(bundle_path = Bundler.bundle_path) + lock_file_path = File.join(bundle_path, "bundler.lock") + has_lock = false + + File.open(lock_file_path, "w") do |f| + f.flock(File::LOCK_EX) + has_lock = true + yield + f.flock(File::LOCK_UN) + end + rescue Errno::EACCES, Errno::ENOLCK, Errno::ENOTSUP, Errno::EPERM, Errno::EROFS + # In the case the user does not have access to + # create the lock file or is using NFS where + # locks are not available we skip locking. + yield + ensure + FileUtils.rm_f(lock_file_path) if has_lock + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/remote_specification.rb b/games/FNaFB2/Ruby/stdlib/bundler/remote_specification.rb new file mode 100644 index 0000000..34d7fd1 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/remote_specification.rb @@ -0,0 +1,121 @@ +# frozen_string_literal: true + +module Bundler + # Represents a lazily loaded gem specification, where the full specification + # is on the source server in rubygems' "quick" index. The proxy object is to + # be seeded with what we're given from the source's abbreviated index - the + # full specification will only be fetched when necessary. + class RemoteSpecification + include MatchRemoteMetadata + include MatchPlatform + include Comparable + + attr_reader :name, :version, :platform + attr_writer :dependencies + attr_accessor :source, :remote + + def initialize(name, version, platform, spec_fetcher) + @name = name + @version = Gem::Version.create version + @original_platform = platform || Gem::Platform::RUBY + @platform = Gem::Platform.new(platform) + @spec_fetcher = spec_fetcher + @dependencies = nil + end + + # Needed before installs, since the arch matters then and quick + # specs don't bother to include the arch in the platform string + def fetch_platform + @platform = _remote_specification.platform + end + + def identifier + @__identifier ||= [name, version, @platform.to_s] + end + + def full_name + if @platform == Gem::Platform::RUBY + "#{@name}-#{@version}" + else + "#{@name}-#{@version}-#{@platform}" + end + end + + # Compare this specification against another object. Using sort_obj + # is compatible with Gem::Specification and other Bundler or RubyGems + # objects. Otherwise, use the default Object comparison. + def <=>(other) + if other.respond_to?(:sort_obj) + sort_obj <=> other.sort_obj + else + super + end + end + + # Because Rubyforge cannot be trusted to provide valid specifications + # once the remote gem is downloaded, the backend specification will + # be swapped out. + def __swap__(spec) + raise APIResponseInvalidDependenciesError unless spec.dependencies.all? {|d| d.is_a?(Gem::Dependency) } + + SharedHelpers.ensure_same_dependencies(self, dependencies, spec.dependencies) + @_remote_specification = spec + end + + # Create a delegate used for sorting. This strategy is copied from + # RubyGems 2.23 and ensures that Bundler's specifications can be + # compared and sorted with RubyGems' own specifications. + # + # @see #<=> + # @see Gem::Specification#sort_obj + # + # @return [Array] an object you can use to compare and sort this + # specification against other specifications + def sort_obj + [@name, @version, @platform == Gem::Platform::RUBY ? -1 : 1] + end + + def to_s + "#<#{self.class} name=#{name} version=#{version} platform=#{platform}>" + end + + def dependencies + @dependencies ||= begin + deps = method_missing(:dependencies) + + # allow us to handle when the specs dependencies are an array of array of string + # in order to delay the crash to `#__swap__` where it results in a friendlier error + # see https://github.com/rubygems/bundler/issues/5797 + deps = deps.map {|d| d.is_a?(Gem::Dependency) ? d : Gem::Dependency.new(*d) } + + deps + end + end + + def git_version + return unless loaded_from && source.is_a?(Bundler::Source::Git) + " #{source.revision[0..6]}" + end + + private + + def to_ary + nil + end + + def _remote_specification + @_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @original_platform]) + @_remote_specification || raise(GemspecError, "Gemspec data for #{full_name} was" \ + " missing from the server! Try installing with `--full-index` as a workaround.") + end + + def method_missing(method, *args, &blk) + _remote_specification.send(method, *args, &blk) + end + + def respond_to?(method, include_all = false) + super || _remote_specification.respond_to?(method, include_all) + end + public :respond_to? + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/resolver.rb b/games/FNaFB2/Ruby/stdlib/bundler/resolver.rb new file mode 100644 index 0000000..115c5cf --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/resolver.rb @@ -0,0 +1,380 @@ +# frozen_string_literal: true + +module Bundler + class Resolver + require_relative "vendored_molinillo" + require_relative "resolver/base" + require_relative "resolver/spec_group" + + include GemHelpers + + def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms) + @source_requirements = source_requirements + @base = Resolver::Base.new(base, additional_base_requirements) + @resolver = Molinillo::Resolver.new(self, self) + @results_for = {} + @search_for = {} + @platforms = platforms + @resolving_only_for_ruby = platforms == [Gem::Platform::RUBY] + @gem_version_promoter = gem_version_promoter + end + + def start(requirements, exclude_specs: []) + @metadata_requirements, regular_requirements = requirements.partition {|dep| dep.name.end_with?("\0") } + + exclude_specs.each do |spec| + remove_from_candidates(spec) + end + + requirements.each {|dep| prerelease_specified[dep.name] ||= dep.prerelease? } + + verify_gemfile_dependencies_are_found!(requirements) + result = @resolver.resolve(requirements). + map(&:payload). + reject {|sg| sg.name.end_with?("\0") }. + map(&:to_specs). + flatten + + SpecSet.new(SpecSet.new(result).for(regular_requirements, false, @platforms)) + rescue Molinillo::VersionConflict => e + conflicts = e.conflicts + + deps_to_unlock = conflicts.values.inject([]) do |deps, conflict| + deps |= conflict.requirement_trees.flatten.map {|req| base_requirements[req.name] }.compact + end + + if deps_to_unlock.any? + @base.unlock_deps(deps_to_unlock) + reset_spec_cache + retry + end + + message = version_conflict_message(e) + raise VersionConflict.new(conflicts.keys.uniq, message) + rescue Molinillo::CircularDependencyError => e + names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" } + raise CyclicDependencyError, "Your bundle requires gems that depend" \ + " on each other, creating an infinite loop. Please remove" \ + " #{names.count > 1 ? "either " : ""}#{names.join(" or ")}" \ + " and try again." + end + + include Molinillo::UI + + # Conveys debug information to the user. + # + # @param [Integer] depth the current depth of the resolution process. + # @return [void] + def debug(depth = 0) + return unless debug? + debug_info = yield + debug_info = debug_info.inspect unless debug_info.is_a?(String) + puts debug_info.split("\n").map {|s| depth == 0 ? "BUNDLER: #{s}" : "BUNDLER(#{depth}): #{s}" } + end + + def debug? + return @debug_mode if defined?(@debug_mode) + @debug_mode = + ENV["BUNDLER_DEBUG_RESOLVER"] || + ENV["BUNDLER_DEBUG_RESOLVER_TREE"] || + ENV["DEBUG_RESOLVER"] || + ENV["DEBUG_RESOLVER_TREE"] || + false + end + + def before_resolution + Bundler.ui.info "Resolving dependencies...", debug? + end + + def after_resolution + Bundler.ui.info "" + end + + def indicate_progress + Bundler.ui.info ".", false unless debug? + end + + include Molinillo::SpecificationProvider + + def dependencies_for(specification) + specification.dependencies_for_activated_platforms + end + + def search_for(dependency) + @search_for[dependency] ||= begin + name = dependency.name + locked_results = @base[name].select {|spec| requirement_satisfied_by?(dependency, nil, spec) } + locked_requirement = base_requirements[name] + results = results_for(dependency) + locked_results + results = results.select {|spec| requirement_satisfied_by?(locked_requirement, nil, spec) } if locked_requirement + dep_platforms = dependency.gem_platforms(@platforms) + + @gem_version_promoter.sort_versions(dependency, results).group_by(&:version).reduce([]) do |groups, (_, specs)| + relevant_platforms = dep_platforms.select {|platform| specs.any? {|spec| spec.match_platform(platform) } } + next groups unless relevant_platforms.any? + + ruby_specs = select_best_platform_match(specs, Gem::Platform::RUBY) + if ruby_specs.any? + spec_group_ruby = SpecGroup.new(ruby_specs, [Gem::Platform::RUBY]) + spec_group_ruby.force_ruby_platform = dependency.force_ruby_platform + groups << spec_group_ruby + end + + next groups if @resolving_only_for_ruby || dependency.force_ruby_platform + + platform_specs = relevant_platforms.flat_map {|platform| select_best_platform_match(specs, platform) } + next groups if platform_specs == ruby_specs + + spec_group = SpecGroup.new(platform_specs, relevant_platforms) + groups << spec_group + + groups + end + end + end + + def index_for(dependency) + source_for(dependency.name).specs + end + + def source_for(name) + @source_requirements[name] || @source_requirements[:default] + end + + def results_for(dependency) + @results_for[dependency] ||= index_for(dependency).search(dependency) + end + + def name_for(dependency) + dependency.name + end + + def name_for_explicit_dependency_source + Bundler.default_gemfile.basename.to_s + rescue StandardError + "Gemfile" + end + + def requirement_satisfied_by?(requirement, activated, spec) + requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec) + end + + def sort_dependencies(dependencies, activated, conflicts) + dependencies.sort_by do |dependency| + name = name_for(dependency) + vertex = activated.vertex_named(name) + [ + @base[name].any? ? 0 : 1, + vertex.payload ? 0 : 1, + vertex.root? ? 0 : 1, + amount_constrained(dependency), + conflicts[name] ? 0 : 1, + vertex.payload ? 0 : search_for(dependency).count, + ] + end + end + + private + + def base_requirements + @base.base_requirements + end + + def prerelease_specified + @gem_version_promoter.prerelease_specified + end + + def remove_from_candidates(spec) + @base.delete(spec) + + @results_for.keys.each do |dep| + next unless dep.name == spec.name + + @results_for[dep].reject {|s| s.name == spec.name && s.version == spec.version } + end + + reset_spec_cache + end + + def reset_spec_cache + @search_for = {} + @gem_version_promoter.reset + end + + # returns an integer \in (-\infty, 0] + # a number closer to 0 means the dependency is less constraining + # + # dependencies w/ 0 or 1 possibilities (ignoring version requirements) + # are given very negative values, so they _always_ sort first, + # before dependencies that are unconstrained + def amount_constrained(dependency) + @amount_constrained ||= {} + @amount_constrained[dependency.name] ||= if (base = @base[dependency.name]) && !base.empty? + dependency.requirement.satisfied_by?(base.first.version) ? 0 : 1 + else + all = index_for(dependency).search(dependency.name).size + + if all <= 1 + all - 1_000_000 + else + search = search_for(dependency) + search = prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? } + search - all + end + end + end + + def verify_gemfile_dependencies_are_found!(requirements) + requirements.map! do |requirement| + name = requirement.name + next requirement if name == "bundler" + next if requirement.gem_platforms(@platforms).empty? + next requirement unless search_for(requirement).empty? + next unless requirement.current_platform? + + raise GemNotFound, gem_not_found_message(name, requirement, source_for(name)) + end.compact! + end + + def gem_not_found_message(name, requirement, source, extra_message = "") + specs = source.specs.search(name).sort_by {|s| [s.version, s.platform.to_s] } + matching_part = name + requirement_label = SharedHelpers.pretty_dependency(requirement) + cache_message = begin + " or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist? + rescue GemfileNotFound + nil + end + specs_matching_requirement = specs.select {| spec| requirement.matches_spec?(spec) } + + if specs_matching_requirement.any? + specs = specs_matching_requirement + matching_part = requirement_label + platforms = requirement.gem_platforms(@platforms) + platform_label = platforms.size == 1 ? "platform '#{platforms.first}" : "platforms '#{platforms.join("', '")}" + requirement_label = "#{requirement_label}' with #{platform_label}" + end + + message = String.new("Could not find gem '#{requirement_label}'#{extra_message} in #{source}#{cache_message}.\n") + + if specs.any? + message << "\nThe source contains the following gems matching '#{matching_part}':\n" + message << specs.map {|s| " * #{s.full_name}" }.join("\n") + end + + message + end + + def version_conflict_message(e) + # only show essential conflicts, if possible + conflicts = e.conflicts.dup + + if conflicts["bundler"] + conflicts.replace("bundler" => conflicts["bundler"]) + else + conflicts.delete_if do |_name, conflict| + deps = conflict.requirement_trees.map(&:last).flatten(1) + !Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement))) + end + end + + e = Molinillo::VersionConflict.new(conflicts, e.specification_provider) unless conflicts.empty? + + e.message_with_trees( + :full_message_for_conflict => lambda do |name, conflict| + trees = conflict.requirement_trees + + # called first, because we want to reduce the amount of work required to find maximal empty sets + trees = trees.uniq {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } } + + # bail out if tree size is too big for Array#combination to make any sense + if trees.size <= 15 + maximal = 1.upto(trees.size).map do |size| + trees.map(&:last).flatten(1).combination(size).to_a + end.flatten(1).select do |deps| + Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement))) + end.min_by(&:size) + + trees.reject! {|t| !maximal.include?(t.last) } if maximal + + trees.sort_by! {|t| t.reverse.map(&:name) } + end + + if trees.size > 1 || name == "bundler" + o = if name.end_with?("\0") + String.new("Bundler found conflicting requirements for the #{name} version:") + else + String.new("Bundler could not find compatible versions for gem \"#{name}\":") + end + o << %(\n) + o << %( In #{name_for_explicit_dependency_source}:\n) + o << trees.map do |tree| + t = "".dup + depth = 2 + + base_tree = tree.first + base_tree_name = base_tree.name + + if base_tree_name.end_with?("\0") + t = nil + else + tree.each do |req| + t << " " * depth << SharedHelpers.pretty_dependency(req) + unless tree.last == req + if spec = conflict.activated_by_name[req.name] + t << %( was resolved to #{spec.version}, which) + end + t << %( depends on) + end + t << %(\n) + depth += 1 + end + end + t + end.compact.join("\n") + else + o = String.new + end + + if name == "bundler" + o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION})) + + conflict_dependency = conflict.requirement + conflict_requirement = conflict_dependency.requirement + other_bundler_required = !conflict_requirement.satisfied_by?(Gem::Version.new(Bundler::VERSION)) + + if other_bundler_required + o << "\n\n" + + candidate_specs = source_for(:default_bundler).specs.search(conflict_dependency) + if candidate_specs.any? + target_version = candidate_specs.last.version + new_command = [File.basename($PROGRAM_NAME), "_#{target_version}_", *ARGV].join(" ") + o << "Your bundle requires a different version of Bundler than the one you're running.\n" + o << "Install the necessary version with `gem install bundler:#{target_version}` and rerun bundler using `#{new_command}`\n" + else + o << "Your bundle requires a different version of Bundler than the one you're running, and that version could not be found.\n" + end + end + elsif name.end_with?("\0") + o << %(\n Current #{name} version:\n #{SharedHelpers.pretty_dependency(@metadata_requirements.find {|req| req.name == name })}\n\n) + elsif !conflict.existing + o << "\n" + + relevant_source = conflict.requirement.source || source_for(name) + + extra_message = if trees.first.size > 1 + ", which is required by gem '#{SharedHelpers.pretty_dependency(trees.first[-2])}'," + else + "" + end + + o << gem_not_found_message(name, conflict.requirement, relevant_source, extra_message) + end + + o + end + ) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/resolver/base.rb b/games/FNaFB2/Ruby/stdlib/bundler/resolver/base.rb new file mode 100644 index 0000000..a8f42dc --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/resolver/base.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module Bundler + class Resolver + class Base + def initialize(base, additional_base_requirements) + @base = base + @additional_base_requirements = additional_base_requirements + end + + def [](name) + @base[name] + end + + def delete(spec) + @base.delete(spec) + end + + def base_requirements + @base_requirements ||= build_base_requirements + end + + def unlock_deps(deps) + exact, lower_bound = deps.partition(&:specific?) + + exact.each do |exact_dep| + @base.delete_by_name_and_version(exact_dep.name, exact_dep.requirement.requirements.first.last) + end + + lower_bound.each do |lower_bound_dep| + @additional_base_requirements.delete(lower_bound_dep) + end + + @base_requirements = nil + end + + private + + def build_base_requirements + base_requirements = {} + @base.each do |ls| + dep = Dependency.new(ls.name, ls.version) + base_requirements[ls.name] = dep + end + @additional_base_requirements.each {|d| base_requirements[d.name] = d } + base_requirements + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/resolver/spec_group.rb b/games/FNaFB2/Ruby/stdlib/bundler/resolver/spec_group.rb new file mode 100644 index 0000000..ac32c3c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/resolver/spec_group.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +module Bundler + class Resolver + class SpecGroup + attr_accessor :name, :version, :source + attr_accessor :activated_platforms, :force_ruby_platform + + def initialize(specs, relevant_platforms) + @exemplary_spec = specs.first + @name = @exemplary_spec.name + @version = @exemplary_spec.version + @source = @exemplary_spec.source + + @activated_platforms = relevant_platforms + @specs = specs + end + + def to_specs + @specs.map do |s| + lazy_spec = LazySpecification.new(name, version, s.platform, source) + lazy_spec.force_ruby_platform = force_ruby_platform + lazy_spec.dependencies.replace s.dependencies + lazy_spec + end + end + + def to_s + activated_platforms_string = sorted_activated_platforms.join(", ") + "#{name} (#{version}) (#{activated_platforms_string})" + end + + def dependencies_for_activated_platforms + @dependencies_for_activated_platforms ||= @specs.map do |spec| + __dependencies(spec) + metadata_dependencies(spec) + end.flatten.uniq + end + + def ==(other) + return unless other.is_a?(SpecGroup) + name == other.name && + version == other.version && + sorted_activated_platforms == other.sorted_activated_platforms && + source == other.source + end + + def eql?(other) + return unless other.is_a?(SpecGroup) + name.eql?(other.name) && + version.eql?(other.version) && + sorted_activated_platforms.eql?(other.sorted_activated_platforms) && + source.eql?(other.source) + end + + def hash + name.hash ^ version.hash ^ sorted_activated_platforms.hash ^ source.hash + end + + protected + + def sorted_activated_platforms + activated_platforms.sort_by(&:to_s) + end + + private + + def __dependencies(spec) + dependencies = [] + spec.dependencies.each do |dep| + next if dep.type == :development + dependencies << Dependency.new(dep.name, dep.requirement) + end + dependencies + end + + def metadata_dependencies(spec) + return [] if spec.is_a?(LazySpecification) + + [ + metadata_dependency("Ruby", spec.required_ruby_version), + metadata_dependency("RubyGems", spec.required_rubygems_version), + ].compact + end + + def metadata_dependency(name, requirement) + return if requirement.nil? || requirement.none? + + Dependency.new("#{name}\0", requirement) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/retry.rb b/games/FNaFB2/Ruby/stdlib/bundler/retry.rb new file mode 100644 index 0000000..2415ade --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/retry.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module Bundler + # General purpose class for retrying code that may fail + class Retry + attr_accessor :name, :total_runs, :current_run + + class << self + def default_attempts + default_retries + 1 + end + alias_method :attempts, :default_attempts + + def default_retries + Bundler.settings[:retry] + end + end + + def initialize(name, exceptions = nil, retries = self.class.default_retries) + @name = name + @retries = retries + @exceptions = Array(exceptions) || [] + @total_runs = @retries + 1 # will run once, then upto attempts.times + end + + def attempt(&block) + @current_run = 0 + @failed = false + @error = nil + run(&block) while keep_trying? + @result + end + alias_method :attempts, :attempt + + private + + def run(&block) + @failed = false + @current_run += 1 + @result = block.call + rescue StandardError => e + fail_attempt(e) + end + + def fail_attempt(e) + @failed = true + if last_attempt? || @exceptions.any? {|k| e.is_a?(k) } + Bundler.ui.info "" unless Bundler.ui.debug? + raise e + end + return true unless name + Bundler.ui.info "" unless Bundler.ui.debug? # Add new line in case dots preceded this + Bundler.ui.warn "Retrying #{name} due to error (#{current_run.next}/#{total_runs}): #{e.class} #{e.message}", Bundler.ui.debug? + end + + def keep_trying? + return true if current_run.zero? + return false if last_attempt? + return true if @failed + end + + def last_attempt? + current_run >= total_runs + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/ruby_dsl.rb b/games/FNaFB2/Ruby/stdlib/bundler/ruby_dsl.rb new file mode 100644 index 0000000..3b3a058 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/ruby_dsl.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Bundler + module RubyDsl + def ruby(*ruby_version) + options = ruby_version.last.is_a?(Hash) ? ruby_version.pop : {} + ruby_version.flatten! + raise GemfileError, "Please define :engine_version" if options[:engine] && options[:engine_version].nil? + raise GemfileError, "Please define :engine" if options[:engine_version] && options[:engine].nil? + + if options[:engine] == "ruby" && options[:engine_version] && + ruby_version != Array(options[:engine_version]) + raise GemfileEvalError, "ruby_version must match the :engine_version for MRI" + end + @ruby_version = RubyVersion.new(ruby_version, options[:patchlevel], options[:engine], options[:engine_version]) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/ruby_version.rb b/games/FNaFB2/Ruby/stdlib/bundler/ruby_version.rb new file mode 100644 index 0000000..9161c6a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/ruby_version.rb @@ -0,0 +1,124 @@ +# frozen_string_literal: true + +module Bundler + class RubyVersion + attr_reader :versions, + :patchlevel, + :engine, + :engine_versions, + :gem_version, + :engine_gem_version + + def initialize(versions, patchlevel, engine, engine_version) + # The parameters to this method must satisfy the + # following constraints, which are verified in + # the DSL: + # + # * If an engine is specified, an engine version + # must also be specified + # * If an engine version is specified, an engine + # must also be specified + # * If the engine is "ruby", the engine version + # must not be specified, or the engine version + # specified must match the version. + + @versions = Array(versions).map do |v| + op, v = Gem::Requirement.parse(v) + op == "=" ? v.to_s : "#{op} #{v}" + end + + @gem_version = Gem::Requirement.create(@versions.first).requirements.first.last + @input_engine = engine && engine.to_s + @engine = engine && engine.to_s || "ruby" + @engine_versions = (engine_version && Array(engine_version)) || @versions + @engine_gem_version = Gem::Requirement.create(@engine_versions.first).requirements.first.last + @patchlevel = patchlevel || (@gem_version.prerelease? ? "-1" : nil) + end + + def to_s(versions = self.versions) + output = String.new("ruby #{versions_string(versions)}") + output << "p#{patchlevel}" if patchlevel && patchlevel != "-1" + output << " (#{engine} #{versions_string(engine_versions)})" unless engine == "ruby" + + output + end + + # @private + PATTERN = / + ruby\s + (\d+\.\d+\.\d+(?:\.\S+)?) # ruby version + (?:p(-?\d+))? # optional patchlevel + (?:\s\((\S+)\s(.+)\))? # optional engine info + /xo.freeze + + # Returns a RubyVersion from the given string. + # @param [String] the version string to match. + # @return [RubyVersion,Nil] The version if the string is a valid RubyVersion + # description, and nil otherwise. + def self.from_string(string) + new($1, $2, $3, $4) if string =~ PATTERN + end + + def single_version_string + to_s(gem_version) + end + + def ==(other) + versions == other.versions && + engine == other.engine && + engine_versions == other.engine_versions && + patchlevel == other.patchlevel + end + + def host + @host ||= [ + RbConfig::CONFIG["host_cpu"], + RbConfig::CONFIG["host_vendor"], + RbConfig::CONFIG["host_os"], + ].join("-") + end + + # Returns a tuple of these things: + # [diff, this, other] + # The priority of attributes are + # 1. engine + # 2. ruby_version + # 3. engine_version + def diff(other) + raise ArgumentError, "Can only diff with a RubyVersion, not a #{other.class}" unless other.is_a?(RubyVersion) + if engine != other.engine && @input_engine + [:engine, engine, other.engine] + elsif versions.empty? || !matches?(versions, other.gem_version) + [:version, versions_string(versions), versions_string(other.versions)] + elsif @input_engine && !matches?(engine_versions, other.engine_gem_version) + [:engine_version, versions_string(engine_versions), versions_string(other.engine_versions)] + elsif patchlevel && (!patchlevel.is_a?(String) || !other.patchlevel.is_a?(String) || !matches?(patchlevel, other.patchlevel)) + [:patchlevel, patchlevel, other.patchlevel] + end + end + + def versions_string(versions) + Array(versions).join(", ") + end + + def self.system + ruby_engine = RUBY_ENGINE.dup + ruby_version = Gem.ruby_version.to_s + ruby_engine_version = RUBY_ENGINE == "ruby" ? ruby_version : RUBY_ENGINE_VERSION.dup + patchlevel = RUBY_PATCHLEVEL.to_s + + @ruby_version ||= RubyVersion.new(ruby_version, patchlevel, ruby_engine, ruby_engine_version) + end + + private + + def matches?(requirements, version) + # Handles RUBY_PATCHLEVEL of -1 for instances like ruby-head + return requirements == version if requirements.to_s == "-1" || version.to_s == "-1" + + Array(requirements).all? do |requirement| + Gem::Requirement.create(requirement).satisfied_by?(Gem::Version.create(version)) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/rubygems_ext.rb b/games/FNaFB2/Ruby/stdlib/bundler/rubygems_ext.rb new file mode 100644 index 0000000..12d6789 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/rubygems_ext.rb @@ -0,0 +1,348 @@ +# frozen_string_literal: true + +require "pathname" + +require "rubygems/specification" + +# We can't let `Gem::Source` be autoloaded in the `Gem::Specification#source` +# redefinition below, so we need to load it upfront. The reason is that if +# Bundler monkeypatches are loaded before RubyGems activates an executable (for +# example, through `ruby -rbundler -S irb`), gem activation might end up calling +# the redefined `Gem::Specification#source` and triggering the `Gem::Source` +# autoload. That would result in requiring "rubygems/source" inside another +# require, which would trigger a monitor error and cause the `autoload` to +# eventually fail. A better solution is probably to completely avoid autoloading +# `Gem::Source` from the redefined `Gem::Specification#source`. +require "rubygems/source" + +require_relative "match_metadata" +require_relative "match_platform" + +# Cherry-pick fixes to `Gem.ruby_version` to be useful for modern Bundler +# versions and ignore patchlevels +# (https://github.com/rubygems/rubygems/pull/5472, +# https://github.com/rubygems/rubygems/pull/5486). May be removed once RubyGems +# 3.3.12 support is dropped. +unless Gem.ruby_version.to_s == RUBY_VERSION || RUBY_PATCHLEVEL == -1 + Gem.instance_variable_set(:@ruby_version, Gem::Version.new(RUBY_VERSION)) +end + +module Gem + class Specification + include ::Bundler::MatchMetadata + include ::Bundler::MatchPlatform + + attr_accessor :remote, :location, :relative_loaded_from + + remove_method :source + attr_writer :source + def source + (defined?(@source) && @source) || Gem::Source::Installed.new + end + + alias_method :rg_full_gem_path, :full_gem_path + alias_method :rg_loaded_from, :loaded_from + + def full_gem_path + if source.respond_to?(:root) + Pathname.new(loaded_from).dirname.expand_path(source.root).to_s.tap {|x| x.untaint if RUBY_VERSION < "2.7" } + else + rg_full_gem_path + end + end + + def loaded_from + if relative_loaded_from + source.path.join(relative_loaded_from).to_s + else + rg_loaded_from + end + end + + def load_paths + full_require_paths + end + + alias_method :rg_extension_dir, :extension_dir + def extension_dir + @bundler_extension_dir ||= if source.respond_to?(:extension_dir_name) + unique_extension_dir = [source.extension_dir_name, File.basename(full_gem_path)].uniq.join("-") + File.expand_path(File.join(extensions_dir, unique_extension_dir)) + else + rg_extension_dir + end + end + + remove_method :gem_dir if instance_methods(false).include?(:gem_dir) + def gem_dir + full_gem_path + end + + unless const_defined?(:LATEST_RUBY_WITHOUT_PATCH_VERSIONS) + LATEST_RUBY_WITHOUT_PATCH_VERSIONS = Gem::Version.new("2.1") + + alias_method :rg_required_ruby_version=, :required_ruby_version= + def required_ruby_version=(req) + self.rg_required_ruby_version = req + + @required_ruby_version.requirements.map! do |op, v| + if v >= LATEST_RUBY_WITHOUT_PATCH_VERSIONS && v.release.segments.size == 4 + [op == "~>" ? "=" : op, Gem::Version.new(v.segments.tap {|s| s.delete_at(3) }.join("."))] + else + [op, v] + end + end + end + end + + def groups + @groups ||= [] + end + + def git_version + return unless loaded_from && source.is_a?(Bundler::Source::Git) + " #{source.revision[0..6]}" + end + + def to_gemfile(path = nil) + gemfile = String.new("source 'https://rubygems.org'\n") + gemfile << dependencies_to_gemfile(nondevelopment_dependencies) + unless development_dependencies.empty? + gemfile << "\n" + gemfile << dependencies_to_gemfile(development_dependencies, :development) + end + gemfile + end + + # Backfill missing YAML require when not defined. Fixed since 3.1.0.pre1. + module YamlBackfiller + def to_yaml(opts = {}) + Gem.load_yaml unless defined?(::YAML) + + super(opts) + end + end + + prepend YamlBackfiller + + def nondevelopment_dependencies + dependencies - development_dependencies + end + + def deleted_gem? + !default_gem? && !File.directory?(full_gem_path) + end + + private + + def dependencies_to_gemfile(dependencies, group = nil) + gemfile = String.new + if dependencies.any? + gemfile << "group :#{group} do\n" if group + dependencies.each do |dependency| + gemfile << " " if group + gemfile << %(gem "#{dependency.name}") + req = dependency.requirements_list.first + gemfile << %(, "#{req}") if req + gemfile << "\n" + end + gemfile << "end\n" if group + end + gemfile + end + end + + class Dependency + attr_accessor :source, :groups + + alias_method :eql?, :== + + def force_ruby_platform + false + end + + def encode_with(coder) + to_yaml_properties.each do |ivar| + coder[ivar.to_s.sub(/^@/, "")] = instance_variable_get(ivar) + end + end + + def to_yaml_properties + instance_variables.reject {|p| ["@source", "@groups"].include?(p.to_s) } + end + + def to_lock + out = String.new(" #{name}") + unless requirement.none? + reqs = requirement.requirements.map {|o, v| "#{o} #{v}" }.sort.reverse + out << " (#{reqs.join(", ")})" + end + out + end + end + + # comparison is done order independently since rubygems 3.2.0.rc.2 + unless Gem::Requirement.new("> 1", "< 2") == Gem::Requirement.new("< 2", "> 1") + class Requirement + module OrderIndependentComparison + def ==(other) + return unless Gem::Requirement === other + + if _requirements_sorted? && other._requirements_sorted? + super + else + _with_sorted_requirements == other._with_sorted_requirements + end + end + + protected + + def _requirements_sorted? + return @_are_requirements_sorted if defined?(@_are_requirements_sorted) + strings = as_list + @_are_requirements_sorted = strings == strings.sort + end + + def _with_sorted_requirements + @_with_sorted_requirements ||= _requirements_sorted? ? self : self.class.new(as_list.sort) + end + end + + prepend OrderIndependentComparison + end + end + + if Gem::Requirement.new("~> 2.0").hash == Gem::Requirement.new("~> 2.0.0").hash + class Requirement + module CorrectHashForLambdaOperator + def hash + if requirements.any? {|r| r.first == "~>" } + requirements.map {|r| r.first == "~>" ? [r[0], r[1].to_s] : r }.sort.hash + else + super + end + end + end + + prepend CorrectHashForLambdaOperator + end + end + + require "rubygems/platform" + + class Platform + JAVA = Gem::Platform.new("java") + MSWIN = Gem::Platform.new("mswin32") + MSWIN64 = Gem::Platform.new("mswin64") + MINGW = Gem::Platform.new("x86-mingw32") + X64_MINGW = [Gem::Platform.new("x64-mingw32"), + Gem::Platform.new("x64-mingw-ucrt")].freeze + WINDOWS = [MSWIN, MSWIN64, MINGW, X64_MINGW].flatten.freeze + X64_LINUX = Gem::Platform.new("x86_64-linux") + X64_LINUX_MUSL = Gem::Platform.new("x86_64-linux-musl") + + if X64_LINUX === X64_LINUX_MUSL + remove_method :=== + + def ===(other) + return nil unless Gem::Platform === other + + # universal-mingw32 matches x64-mingw-ucrt + return true if (@cpu == "universal" || other.cpu == "universal") && + @os.start_with?("mingw") && other.os.start_with?("mingw") + + # cpu + ([nil,"universal"].include?(@cpu) || [nil, "universal"].include?(other.cpu) || @cpu == other.cpu || + (@cpu == "arm" && other.cpu.start_with?("arm"))) && + + # os + @os == other.os && + + # version + ( + (@os != "linux" && (@version.nil? || other.version.nil?)) || + (@os == "linux" && (normalized_linux_version_ext == other.normalized_linux_version_ext || ["musl#{@version}", "musleabi#{@version}", "musleabihf#{@version}"].include?(other.version))) || + @version == other.version + ) + end + + # This is a copy of RubyGems 3.3.23 or higher `normalized_linux_method`. + # Once only 3.3.23 is supported, we can use the method in RubyGems. + def normalized_linux_version_ext + return nil unless @version + + without_gnu_nor_abi_modifiers = @version.sub(/\Agnu/, "").sub(/eabi(hf)?\Z/, "") + return nil if without_gnu_nor_abi_modifiers.empty? + + without_gnu_nor_abi_modifiers + end + end + end + + Platform.singleton_class.module_eval do + unless Platform.singleton_methods.include?(:match_spec?) + def match_spec?(spec) + match_gem?(spec.platform, spec.name) + end + + def match_gem?(platform, gem_name) + match_platforms?(platform, Gem.platforms) + end + end + + match_platforms_defined = Gem::Platform.respond_to?(:match_platforms?, true) + + if !match_platforms_defined || Gem::Platform.send(:match_platforms?, Gem::Platform::X64_LINUX_MUSL, [Gem::Platform::X64_LINUX]) + + private + + remove_method :match_platforms? if match_platforms_defined + + def match_platforms?(platform, platforms) + platforms.any? do |local_platform| + platform.nil? || + local_platform == platform || + (local_platform != Gem::Platform::RUBY && platform =~ local_platform) + end + end + end + end + + # On universal Rubies, resolve the "universal" arch to the real CPU arch, without changing the extension directory. + class Specification + if /^universal\.(?.*?)-/ =~ (CROSS_COMPILING || RUBY_PLATFORM) + local_platform = Platform.local + if local_platform.cpu == "universal" + ORIGINAL_LOCAL_PLATFORM = local_platform.to_s.freeze + + local_platform.cpu = if arch == "arm64e" # arm64e is only permitted for Apple system binaries + "arm64" + else + arch + end + + def extensions_dir + Gem.default_ext_dir_for(base_dir) || + File.join(base_dir, "extensions", ORIGINAL_LOCAL_PLATFORM, + Gem.extension_api_version) + end + end + end + end + + require "rubygems/util" + + Util.singleton_class.module_eval do + if Util.singleton_methods.include?(:glob_files_in_dir) # since 3.0.0.beta.2 + remove_method :glob_files_in_dir + end + + def glob_files_in_dir(glob, base_path) + if RUBY_VERSION >= "2.5" + Dir.glob(glob, :base => base_path).map! {|f| File.expand_path(f, base_path) } + else + Dir.glob(File.join(base_path.to_s.gsub(/[\[\]]/, '\\\\\\&'), glob)).map! {|f| File.expand_path(f) } + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/rubygems_gem_installer.rb b/games/FNaFB2/Ruby/stdlib/bundler/rubygems_gem_installer.rb new file mode 100644 index 0000000..13c2d25 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/rubygems_gem_installer.rb @@ -0,0 +1,170 @@ +# frozen_string_literal: true + +require "rubygems/installer" + +module Bundler + class RubyGemsGemInstaller < Gem::Installer + def check_executable_overwrite(filename) + # Bundler needs to install gems regardless of binstub overwriting + end + + def install + pre_install_checks + + run_pre_install_hooks + + spec.loaded_from = spec_file + + # Completely remove any previous gem files + strict_rm_rf gem_dir + strict_rm_rf spec.extension_dir + + SharedHelpers.filesystem_access(gem_dir, :create) do + FileUtils.mkdir_p gem_dir, :mode => 0o755 + end + + extract_files + + build_extensions if spec.extensions.any? + write_build_info_file + run_post_build_hooks + + generate_bin + generate_plugins + + write_spec + + SharedHelpers.filesystem_access("#{gem_home}/cache", :write) do + write_cache_file + end + + say spec.post_install_message unless spec.post_install_message.nil? + + run_post_install_hooks + + spec + end + + def generate_plugins + return unless Gem::Installer.instance_methods(false).include?(:generate_plugins) + + latest = Gem::Specification.stubs_for(spec.name).first + return if latest && latest.version > spec.version + + ensure_writable_dir @plugins_dir + + if spec.plugins.empty? + remove_plugins_for(spec, @plugins_dir) + else + regenerate_plugins_for(spec, @plugins_dir) + end + end + + def pre_install_checks + super && validate_bundler_checksum(options[:bundler_expected_checksum]) + end + + def build_extensions + extension_cache_path = options[:bundler_extension_cache_path] + extension_dir = spec.extension_dir + unless extension_cache_path && extension_dir + prepare_extension_build(extension_dir) + return super + end + + build_complete = SharedHelpers.filesystem_access(extension_cache_path.join("gem.build_complete"), :read, &:file?) + if build_complete && !options[:force] + SharedHelpers.filesystem_access(File.dirname(extension_dir)) do |p| + FileUtils.mkpath p + end + SharedHelpers.filesystem_access(extension_cache_path) do + FileUtils.cp_r extension_cache_path, extension_dir + end + else + prepare_extension_build(extension_dir) + super + SharedHelpers.filesystem_access(extension_cache_path.parent, &:mkpath) + SharedHelpers.filesystem_access(extension_cache_path) do + FileUtils.cp_r extension_dir, extension_cache_path + end + end + end + + def spec + if Bundler.rubygems.provides?("< 3.3.12") # RubyGems implementation rescues and re-raises errors before 3.3.12 and we don't want that + @package.spec + else + super + end + end + + private + + def prepare_extension_build(extension_dir) + SharedHelpers.filesystem_access(extension_dir, :create) do + FileUtils.mkdir_p extension_dir + end + require "shellwords" unless Bundler.rubygems.provides?(">= 3.2.25") + end + + def strict_rm_rf(dir) + Bundler.rm_rf dir + rescue Errno::ENOTEMPTY => e + raise DirectoryRemovalError.new(e.cause, "Could not delete previous installation of `#{dir}`") + end + + def validate_bundler_checksum(checksum) + return true if Bundler.settings[:disable_checksum_validation] + return true unless checksum + return true unless source = @package.instance_variable_get(:@gem) + return true unless source.respond_to?(:with_read_io) + digest = source.with_read_io do |io| + digest = SharedHelpers.digest(:SHA256).new + digest << io.read(16_384) until io.eof? + io.rewind + send(checksum_type(checksum), digest) + end + unless digest == checksum + raise SecurityError, <<-MESSAGE + Bundler cannot continue installing #{spec.name} (#{spec.version}). + The checksum for the downloaded `#{spec.full_name}.gem` does not match \ + the checksum given by the server. This means the contents of the downloaded \ + gem is different from what was uploaded to the server, and could be a potential security issue. + + To resolve this issue: + 1. delete the downloaded gem located at: `#{spec.gem_dir}/#{spec.full_name}.gem` + 2. run `bundle install` + + If you wish to continue installing the downloaded gem, and are certain it does not pose a \ + security issue despite the mismatching checksum, do the following: + 1. run `bundle config set --local disable_checksum_validation true` to turn off checksum verification + 2. run `bundle install` + + (More info: The expected SHA256 checksum was #{checksum.inspect}, but the \ + checksum for the downloaded gem was #{digest.inspect}.) + MESSAGE + end + true + end + + def checksum_type(checksum) + case checksum.length + when 64 then :hexdigest! + when 44 then :base64digest! + else raise InstallError, "The given checksum for #{spec.full_name} (#{checksum.inspect}) is not a valid SHA256 hexdigest nor base64digest" + end + end + + def hexdigest!(digest) + digest.hexdigest! + end + + def base64digest!(digest) + if digest.respond_to?(:base64digest!) + digest.base64digest! + else + [digest.digest!].pack("m0") + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/rubygems_integration.rb b/games/FNaFB2/Ruby/stdlib/bundler/rubygems_integration.rb new file mode 100644 index 0000000..a6180d5 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/rubygems_integration.rb @@ -0,0 +1,566 @@ +# frozen_string_literal: true + +require "rubygems" unless defined?(Gem) + +module Bundler + class RubygemsIntegration + if defined?(Gem::Ext::Builder::CHDIR_MONITOR) + EXT_LOCK = Gem::Ext::Builder::CHDIR_MONITOR + else + require "monitor" + + EXT_LOCK = Monitor.new + end + + def initialize + @replaced_methods = {} + backport_ext_builder_monitor + end + + def version + @version ||= Gem.rubygems_version + end + + def provides?(req_str) + Gem::Requirement.new(req_str).satisfied_by?(version) + end + + def supports_bundler_trampolining? + provides?(">= 3.3.0.a") + end + + def build_args + require "rubygems/command" + Gem::Command.build_args + end + + def build_args=(args) + require "rubygems/command" + Gem::Command.build_args = args + end + + def loaded_specs(name) + Gem.loaded_specs[name] + end + + def add_to_load_path(paths) + return Gem.add_to_load_path(*paths) if Gem.respond_to?(:add_to_load_path) + + if insert_index = Gem.load_path_insert_index + # Gem directories must come after -I and ENV['RUBYLIB'] + $LOAD_PATH.insert(insert_index, *paths) + else + # We are probably testing in core, -I and RUBYLIB don't apply + $LOAD_PATH.unshift(*paths) + end + end + + def mark_loaded(spec) + if spec.respond_to?(:activated=) + current = Gem.loaded_specs[spec.name] + current.activated = false if current + spec.activated = true + end + Gem.loaded_specs[spec.name] = spec + end + + def validate(spec) + Bundler.ui.silence { spec.validate(false) } + rescue Gem::InvalidSpecificationException => e + error_message = "The gemspec at #{spec.loaded_from} is not valid. Please fix this gemspec.\n" \ + "The validation error was '#{e.message}'\n" + raise Gem::InvalidSpecificationException.new(error_message) + rescue Errno::ENOENT + nil + end + + def set_installed_by_version(spec, installed_by_version = Gem::VERSION) + return unless spec.respond_to?(:installed_by_version=) + spec.installed_by_version = Gem::Version.create(installed_by_version) + end + + def spec_missing_extensions?(spec, default = true) + return spec.missing_extensions? if spec.respond_to?(:missing_extensions?) + + return false if spec.default_gem? + return false if spec.extensions.empty? + + default + end + + def spec_matches_for_glob(spec, glob) + return spec.matches_for_glob(glob) if spec.respond_to?(:matches_for_glob) + + spec.load_paths.map do |lp| + Dir["#{lp}/#{glob}#{suffix_pattern}"] + end.flatten(1) + end + + def stub_set_spec(stub, spec) + stub.instance_variable_set(:@spec, spec) + end + + def path(obj) + obj.to_s + end + + def ruby_engine + Gem.ruby_engine + end + + def read_binary(path) + Gem.read_binary(path) + end + + def inflate(obj) + Gem::Util.inflate(obj) + end + + def correct_for_windows_path(path) + if Gem::Util.respond_to?(:correct_for_windows_path) + Gem::Util.correct_for_windows_path(path) + elsif path[0].chr == "/" && path[1].chr =~ /[a-z]/i && path[2].chr == ":" + path[1..-1] + else + path + end + end + + def gem_dir + Gem.dir + end + + def gem_bindir + Gem.bindir + end + + def user_home + Gem.user_home + end + + def gem_path + Gem.path + end + + def reset + Gem::Specification.reset + end + + def post_reset_hooks + Gem.post_reset_hooks + end + + def suffix_pattern + Gem.suffix_pattern + end + + def gem_cache + gem_path.map {|p| File.expand_path("cache", p) } + end + + def spec_cache_dirs + @spec_cache_dirs ||= begin + dirs = gem_path.map {|dir| File.join(dir, "specifications") } + dirs << Gem.spec_cache_dir if Gem.respond_to?(:spec_cache_dir) # Not in RubyGems 2.0.3 or earlier + dirs.uniq.select {|dir| File.directory? dir } + end + end + + def marshal_spec_dir + Gem::MARSHAL_SPEC_DIR + end + + def clear_paths + Gem.clear_paths + end + + def bin_path(gem, bin, ver) + Gem.bin_path(gem, bin, ver) + end + + def loaded_gem_paths + loaded_gem_paths = Gem.loaded_specs.map {|_, s| s.full_require_paths } + loaded_gem_paths.flatten + end + + def load_plugins + Gem.load_plugins if Gem.respond_to?(:load_plugins) + end + + def load_plugin_files(files) + Gem.load_plugin_files(files) if Gem.respond_to?(:load_plugin_files) + end + + def load_env_plugins + Gem.load_env_plugins if Gem.respond_to?(:load_env_plugins) + end + + def ui=(obj) + Gem::DefaultUserInteraction.ui = obj + end + + def ext_lock + EXT_LOCK + end + + def spec_from_gem(path) + require "rubygems/package" + Gem::Package.new(path).spec + end + + def build_gem(gem_dir, spec) + build(spec) + end + + def security_policy_keys + %w[High Medium Low AlmostNo No].map {|level| "#{level}Security" } + end + + def security_policies + @security_policies ||= begin + require "rubygems/security" + Gem::Security::Policies + rescue LoadError, NameError + {} + end + end + + def reverse_rubygems_kernel_mixin + # Disable rubygems' gem activation system + kernel = (class << ::Kernel; self; end) + [kernel, ::Kernel].each do |k| + if k.private_method_defined?(:gem_original_require) + redefine_method(k, :require, k.instance_method(:gem_original_require)) + end + end + end + + def replace_gem(specs, specs_by_name) + reverse_rubygems_kernel_mixin + + executables = nil + + kernel = (class << ::Kernel; self; end) + [kernel, ::Kernel].each do |kernel_class| + redefine_method(kernel_class, :gem) do |dep, *reqs| + if executables && executables.include?(File.basename(caller.first.split(":").first)) + break + end + + reqs.pop if reqs.last.is_a?(Hash) + + unless dep.respond_to?(:name) && dep.respond_to?(:requirement) + dep = Gem::Dependency.new(dep, reqs) + end + + if spec = specs_by_name[dep.name] + return true if dep.matches_spec?(spec) + end + + message = if spec.nil? + target_file = begin + Bundler.default_gemfile.basename + rescue GemfileNotFound + "inline Gemfile" + end + "#{dep.name} is not part of the bundle." \ + " Add it to your #{target_file}." + else + "can't activate #{dep}, already activated #{spec.full_name}. " \ + "Make sure all dependencies are added to Gemfile." + end + + e = Gem::LoadError.new(message) + e.name = dep.name + if e.respond_to?(:requirement=) + e.requirement = dep.requirement + elsif e.respond_to?(:version_requirement=) + e.version_requirement = dep.requirement + end + raise e + end + + # backwards compatibility shim, see https://github.com/rubygems/bundler/issues/5102 + kernel_class.send(:public, :gem) if Bundler.feature_flag.setup_makes_kernel_gem_public? + end + end + + # Used to make bin stubs that are not created by bundler work + # under bundler. The new Gem.bin_path only considers gems in + # +specs+ + def replace_bin_path(specs_by_name) + gem_class = (class << Gem; self; end) + + redefine_method(gem_class, :find_spec_for_exe) do |gem_name, *args| + exec_name = args.first + raise ArgumentError, "you must supply exec_name" unless exec_name + + spec_with_name = specs_by_name[gem_name] + matching_specs_by_exec_name = specs_by_name.values.select {|s| s.executables.include?(exec_name) } + spec = matching_specs_by_exec_name.delete(spec_with_name) + + unless spec || !matching_specs_by_exec_name.empty? + message = "can't find executable #{exec_name} for gem #{gem_name}" + if spec_with_name.nil? + message += ". #{gem_name} is not currently included in the bundle, " \ + "perhaps you meant to add it to your #{Bundler.default_gemfile.basename}?" + end + raise Gem::Exception, message + end + + unless spec + spec = matching_specs_by_exec_name.shift + warn \ + "Bundler is using a binstub that was created for a different gem (#{spec.name}).\n" \ + "You should run `bundle binstub #{gem_name}` " \ + "to work around a system/bundle conflict." + end + + unless matching_specs_by_exec_name.empty? + conflicting_names = matching_specs_by_exec_name.map(&:name).join(", ") + warn \ + "The `#{exec_name}` executable in the `#{spec.name}` gem is being loaded, but it's also present in other gems (#{conflicting_names}).\n" \ + "If you meant to run the executable for another gem, make sure you use a project specific binstub (`bundle binstub `).\n" \ + "If you plan to use multiple conflicting executables, generate binstubs for them and disambiguate their names." + end + + spec + end + + redefine_method(gem_class, :activate_bin_path) do |name, *args| + exec_name = args.first + return ENV["BUNDLE_BIN_PATH"] if exec_name == "bundle" + + # Copy of Rubygems activate_bin_path impl + requirement = args.last + spec = find_spec_for_exe name, exec_name, [requirement] + + gem_bin = File.join(spec.full_gem_path, spec.bindir, exec_name) + gem_from_path_bin = File.join(File.dirname(spec.loaded_from), spec.bindir, exec_name) + File.exist?(gem_bin) ? gem_bin : gem_from_path_bin + end + + redefine_method(gem_class, :bin_path) do |name, *args| + exec_name = args.first + return ENV["BUNDLE_BIN_PATH"] if exec_name == "bundle" + + spec = find_spec_for_exe(name, *args) + exec_name ||= spec.default_executable + + gem_bin = File.join(spec.full_gem_path, spec.bindir, exec_name) + gem_from_path_bin = File.join(File.dirname(spec.loaded_from), spec.bindir, exec_name) + File.exist?(gem_bin) ? gem_bin : gem_from_path_bin + end + end + + # Replace or hook into RubyGems to provide a bundlerized view + # of the world. + def replace_entrypoints(specs) + specs_by_name = add_default_gems_to(specs) + + replace_gem(specs, specs_by_name) + stub_rubygems(specs) + replace_bin_path(specs_by_name) + + Gem.clear_paths + end + + # Add default gems not already present in specs, and return them as a hash. + def add_default_gems_to(specs) + specs_by_name = specs.reduce({}) do |h, s| + h[s.name] = s + h + end + + Bundler.rubygems.default_stubs.each do |stub| + default_spec = stub.to_spec + default_spec_name = default_spec.name + next if specs_by_name.key?(default_spec_name) + + specs << default_spec + specs_by_name[default_spec_name] = default_spec + end + + specs_by_name + end + + def undo_replacements + @replaced_methods.each do |(sym, klass), method| + redefine_method(klass, sym, method) + end + if Binding.public_method_defined?(:source_location) + post_reset_hooks.reject! {|proc| proc.binding.source_location[0] == __FILE__ } + else + post_reset_hooks.reject! {|proc| proc.binding.eval("__FILE__") == __FILE__ } + end + @replaced_methods.clear + end + + def redefine_method(klass, method, unbound_method = nil, &block) + visibility = method_visibility(klass, method) + begin + if (instance_method = klass.instance_method(method)) && method != :initialize + # doing this to ensure we also get private methods + klass.send(:remove_method, method) + end + rescue NameError + # method isn't defined + nil + end + @replaced_methods[[method, klass]] = instance_method + if unbound_method + klass.send(:define_method, method, unbound_method) + klass.send(visibility, method) + elsif block + klass.send(:define_method, method, &block) + klass.send(visibility, method) + end + end + + def method_visibility(klass, method) + if klass.private_method_defined?(method) + :private + elsif klass.protected_method_defined?(method) + :protected + else + :public + end + end + + def stub_rubygems(specs) + Gem::Specification.all = specs + + Gem.post_reset do + Gem::Specification.all = specs + end + + redefine_method((class << Gem; self; end), :finish_resolve) do |*| + [] + end + end + + def plain_specs + Gem::Specification._all + end + + def plain_specs=(specs) + Gem::Specification.all = specs + end + + def fetch_specs(remote, name) + require "rubygems/remote_fetcher" + path = remote.uri.to_s + "#{name}.#{Gem.marshal_version}.gz" + fetcher = gem_remote_fetcher + fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri + string = fetcher.fetch_path(path) + Bundler.load_marshal(string) + rescue Gem::RemoteFetcher::FetchError + # it's okay for prerelease to fail + raise unless name == "prerelease_specs" + end + + def fetch_all_remote_specs(remote) + specs = fetch_specs(remote, "specs") + pres = fetch_specs(remote, "prerelease_specs") || [] + + specs.concat(pres) + end + + def download_gem(spec, uri, cache_dir) + require "rubygems/remote_fetcher" + uri = Bundler.settings.mirror_for(uri) + fetcher = gem_remote_fetcher + fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri + Bundler::Retry.new("download gem from #{uri}").attempts do + gem_file_name = spec.file_name + local_gem_path = File.join cache_dir, gem_file_name + return if File.exist? local_gem_path + + begin + remote_gem_path = uri + "gems/#{gem_file_name}" + remote_gem_path = remote_gem_path.to_s if provides?("< 3.2.0.rc.1") + + SharedHelpers.filesystem_access(local_gem_path) do + fetcher.cache_update_path remote_gem_path, local_gem_path + end + rescue Gem::RemoteFetcher::FetchError + raise if spec.original_platform == spec.platform + + original_gem_file_name = "#{spec.original_name}.gem" + raise if gem_file_name == original_gem_file_name + + gem_file_name = original_gem_file_name + retry + end + end + rescue Gem::RemoteFetcher::FetchError => e + raise Bundler::HTTPError, "Could not download gem from #{uri} due to underlying error <#{e.message}>" + end + + def gem_remote_fetcher + require "rubygems/remote_fetcher" + proxy = Gem.configuration[:http_proxy] + Gem::RemoteFetcher.new(proxy) + end + + def build(spec, skip_validation = false) + require "rubygems/package" + Gem::Package.build(spec, skip_validation) + end + + def repository_subdirectories + Gem::REPOSITORY_SUBDIRECTORIES + end + + def path_separator + Gem.path_separator + end + + def all_specs + Gem::Specification.stubs.map do |stub| + StubSpecification.from_stub(stub) + end + end + + def backport_ext_builder_monitor + # So we can avoid requiring "rubygems/ext" in its entirety + Gem.module_eval <<-RUBY, __FILE__, __LINE__ + 1 + module Ext + end + RUBY + + require "rubygems/ext/builder" + + Gem::Ext::Builder.class_eval do + unless const_defined?(:CHDIR_MONITOR) + const_set(:CHDIR_MONITOR, EXT_LOCK) + end + + remove_const(:CHDIR_MUTEX) if const_defined?(:CHDIR_MUTEX) + const_set(:CHDIR_MUTEX, const_get(:CHDIR_MONITOR)) + end + end + + def find_bundler(version) + find_name("bundler").find {|s| s.version.to_s == version } + end + + def find_name(name) + Gem::Specification.stubs_for(name).map(&:to_spec) + end + + if Gem::Specification.respond_to?(:default_stubs) + def default_stubs + Gem::Specification.default_stubs("*.gemspec") + end + else + def default_stubs + Gem::Specification.send(:default_stubs, "*.gemspec") + end + end + end + + def self.rubygems + @rubygems ||= RubygemsIntegration.new + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/runtime.rb b/games/FNaFB2/Ruby/stdlib/bundler/runtime.rb new file mode 100644 index 0000000..fc644cc --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/runtime.rb @@ -0,0 +1,311 @@ +# frozen_string_literal: true + +module Bundler + class Runtime + include SharedHelpers + + def initialize(root, definition) + @root = root + @definition = definition + end + + def setup(*groups) + @definition.ensure_equivalent_gemfile_and_lockfile if Bundler.frozen_bundle? + + # Has to happen first + clean_load_path + + specs = @definition.specs_for(groups) + + SharedHelpers.set_bundle_environment + Bundler.rubygems.replace_entrypoints(specs) + + # Activate the specs + load_paths = specs.map do |spec| + check_for_activated_spec!(spec) + + Bundler.rubygems.mark_loaded(spec) + spec.load_paths.reject {|path| $LOAD_PATH.include?(path) } + end.reverse.flatten + + Bundler.rubygems.add_to_load_path(load_paths) + + setup_manpath + + lock(:preserve_unknown_sections => true) + + self + end + + def require(*groups) + groups.map!(&:to_sym) + groups = [:default] if groups.empty? + + @definition.dependencies.each do |dep| + # Skip the dependency if it is not in any of the requested groups, or + # not for the current platform, or doesn't match the gem constraints. + next unless (dep.groups & groups).any? && dep.should_include? + + required_file = nil + + begin + # Loop through all the specified autorequires for the + # dependency. If there are none, use the dependency's name + # as the autorequire. + Array(dep.autorequire || dep.name).each do |file| + # Allow `require: true` as an alias for `require: ` + file = dep.name if file == true + required_file = file + begin + Kernel.require file + rescue RuntimeError => e + raise e if e.is_a?(LoadError) # we handle this a little later + raise Bundler::GemRequireError.new e, + "There was an error while trying to load the gem '#{file}'." + end + end + rescue LoadError => e + raise if dep.autorequire || e.path != required_file + + if dep.autorequire.nil? && dep.name.include?("-") + begin + namespaced_file = dep.name.tr("-", "/") + Kernel.require namespaced_file + rescue LoadError => e + raise if e.path != namespaced_file + end + end + end + end + end + + def self.definition_method(meth) + define_method(meth) do + raise ArgumentError, "no definition when calling Runtime##{meth}" unless @definition + @definition.send(meth) + end + end + private_class_method :definition_method + + definition_method :requested_specs + definition_method :specs + definition_method :dependencies + definition_method :current_dependencies + definition_method :requires + + def lock(opts = {}) + return if @definition.nothing_changed? && !@definition.unlocking? + @definition.lock(Bundler.default_lockfile, opts[:preserve_unknown_sections]) + end + + alias_method :gems, :specs + + def cache(custom_path = nil, local = false) + cache_path = Bundler.app_cache(custom_path) + SharedHelpers.filesystem_access(cache_path) do |p| + FileUtils.mkdir_p(p) + end unless File.exist?(cache_path) + + Bundler.ui.info "Updating files in #{Bundler.settings.app_cache_path}" + + specs_to_cache = if Bundler.settings[:cache_all_platforms] + @definition.resolve.materialized_for_all_platforms + else + begin + specs + rescue GemNotFound + if local + Bundler.ui.warn "Some gems seem to be missing from your #{Bundler.settings.app_cache_path} directory." + end + + raise + end + end + + specs_to_cache.each do |spec| + next if spec.name == "bundler" + next if spec.source.is_a?(Source::Gemspec) + spec.source.cache(spec, custom_path) if spec.source.respond_to?(:cache) + end + + Dir[cache_path.join("*/.git")].each do |git_dir| + FileUtils.rm_rf(git_dir) + FileUtils.touch(File.expand_path("../.bundlecache", git_dir)) + end + + prune_cache(cache_path) unless Bundler.settings[:no_prune] + end + + def prune_cache(cache_path) + SharedHelpers.filesystem_access(cache_path) do |p| + FileUtils.mkdir_p(p) + end unless File.exist?(cache_path) + resolve = @definition.resolve + prune_gem_cache(resolve, cache_path) + prune_git_and_path_cache(resolve, cache_path) + end + + def clean(dry_run = false) + gem_bins = Dir["#{Gem.dir}/bin/*"] + git_dirs = Dir["#{Gem.dir}/bundler/gems/*"] + git_cache_dirs = Dir["#{Gem.dir}/cache/bundler/git/*"] + gem_dirs = Dir["#{Gem.dir}/gems/*"] + gem_files = Dir["#{Gem.dir}/cache/*.gem"] + gemspec_files = Dir["#{Gem.dir}/specifications/*.gemspec"] + extension_dirs = Dir["#{Gem.dir}/extensions/*/*/*"] + Dir["#{Gem.dir}/bundler/gems/extensions/*/*/*"] + spec_gem_paths = [] + # need to keep git sources around + spec_git_paths = @definition.spec_git_paths + spec_git_cache_dirs = [] + spec_gem_executables = [] + spec_cache_paths = [] + spec_gemspec_paths = [] + spec_extension_paths = [] + Bundler.rubygems.add_default_gems_to(specs).values.each do |spec| + spec_gem_paths << spec.full_gem_path + # need to check here in case gems are nested like for the rails git repo + md = %r{(.+bundler/gems/.+-[a-f0-9]{7,12})}.match(spec.full_gem_path) + spec_git_paths << md[1] if md + spec_gem_executables << spec.executables.collect do |executable| + e = "#{Bundler.rubygems.gem_bindir}/#{executable}" + [e, "#{e}.bat"] + end + spec_cache_paths << spec.cache_file + spec_gemspec_paths << spec.spec_file + spec_extension_paths << spec.extension_dir if spec.respond_to?(:extension_dir) + spec_git_cache_dirs << spec.source.cache_path.to_s if spec.source.is_a?(Bundler::Source::Git) + end + spec_gem_paths.uniq! + spec_gem_executables.flatten! + + stale_gem_bins = gem_bins - spec_gem_executables + stale_git_dirs = git_dirs - spec_git_paths - ["#{Gem.dir}/bundler/gems/extensions"] + stale_git_cache_dirs = git_cache_dirs - spec_git_cache_dirs + stale_gem_dirs = gem_dirs - spec_gem_paths + stale_gem_files = gem_files - spec_cache_paths + stale_gemspec_files = gemspec_files - spec_gemspec_paths + stale_extension_dirs = extension_dirs - spec_extension_paths + + removed_stale_gem_dirs = stale_gem_dirs.collect {|dir| remove_dir(dir, dry_run) } + removed_stale_git_dirs = stale_git_dirs.collect {|dir| remove_dir(dir, dry_run) } + output = removed_stale_gem_dirs + removed_stale_git_dirs + + unless dry_run + stale_files = stale_gem_bins + stale_gem_files + stale_gemspec_files + stale_files.each do |file| + SharedHelpers.filesystem_access(File.dirname(file)) do |_p| + FileUtils.rm(file) if File.exist?(file) + end + end + + stale_dirs = stale_git_cache_dirs + stale_extension_dirs + stale_dirs.each do |stale_dir| + SharedHelpers.filesystem_access(stale_dir) do |dir| + FileUtils.rm_rf(dir) if File.exist?(dir) + end + end + end + + output + end + + private + + def prune_gem_cache(resolve, cache_path) + cached = Dir["#{cache_path}/*.gem"] + + cached = cached.delete_if do |path| + spec = Bundler.rubygems.spec_from_gem path + + resolve.any? do |s| + s.name == spec.name && s.version == spec.version && !s.source.is_a?(Bundler::Source::Git) + end + end + + if cached.any? + Bundler.ui.info "Removing outdated .gem files from #{Bundler.settings.app_cache_path}" + + cached.each do |path| + Bundler.ui.info " * #{File.basename(path)}" + File.delete(path) + end + end + end + + def prune_git_and_path_cache(resolve, cache_path) + cached = Dir["#{cache_path}/*/.bundlecache"] + + cached = cached.delete_if do |path| + name = File.basename(File.dirname(path)) + + resolve.any? do |s| + source = s.source + source.respond_to?(:app_cache_dirname) && source.app_cache_dirname == name + end + end + + if cached.any? + Bundler.ui.info "Removing outdated git and path gems from #{Bundler.settings.app_cache_path}" + + cached.each do |path| + path = File.dirname(path) + Bundler.ui.info " * #{File.basename(path)}" + FileUtils.rm_rf(path) + end + end + end + + def setup_manpath + # Add man/ subdirectories from activated bundles to MANPATH for man(1) + manuals = $LOAD_PATH.map do |path| + man_subdir = path.sub(/lib$/, "man") + man_subdir unless Dir[man_subdir + "/man?/"].empty? + end.compact + + return if manuals.empty? + Bundler::SharedHelpers.set_env "MANPATH", manuals.concat( + ENV["MANPATH"] ? ENV["MANPATH"].to_s.split(File::PATH_SEPARATOR) : [""] + ).uniq.join(File::PATH_SEPARATOR) + end + + def remove_dir(dir, dry_run) + full_name = Pathname.new(dir).basename.to_s + + parts = full_name.split("-") + name = parts[0..-2].join("-") + version = parts.last + output = "#{name} (#{version})" + + if dry_run + Bundler.ui.info "Would have removed #{output}" + else + Bundler.ui.info "Removing #{output}" + FileUtils.rm_rf(dir) + end + + output + end + + def check_for_activated_spec!(spec) + return unless activated_spec = Bundler.rubygems.loaded_specs(spec.name) + return if activated_spec.version == spec.version + + suggestion = if activated_spec.default_gem? + "Since #{spec.name} is a default gem, you can either remove your dependency on it" \ + " or try updating to a newer version of bundler that supports #{spec.name} as a default gem." + else + "Prepending `bundle exec` to your command may solve this." + end + + e = Gem::LoadError.new "You have already activated #{activated_spec.name} #{activated_spec.version}, " \ + "but your Gemfile requires #{spec.name} #{spec.version}. #{suggestion}" + e.name = spec.name + if e.respond_to?(:requirement=) + e.requirement = Gem::Requirement.new(spec.version.to_s) + else + e.version_requirement = Gem::Requirement.new(spec.version.to_s) + end + raise e + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/self_manager.rb b/games/FNaFB2/Ruby/stdlib/bundler/self_manager.rb new file mode 100644 index 0000000..827f3f9 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/self_manager.rb @@ -0,0 +1,168 @@ +# frozen_string_literal: true + +module Bundler + # + # This class handles installing and switching to the version of bundler needed + # by an application. + # + class SelfManager + def restart_with_locked_bundler_if_needed + return unless needs_switching? && installed? + + restart_with(lockfile_version) + end + + def install_locked_bundler_and_restart_with_it_if_needed + return unless needs_switching? + + Bundler.ui.info \ + "Bundler #{current_version} is running, but your lockfile was generated with #{lockfile_version}. " \ + "Installing Bundler #{lockfile_version} and restarting using that version." + + install_and_restart_with(lockfile_version) + end + + def update_bundler_and_restart_with_it_if_needed(target) + return unless autoswitching_applies? + + spec = resolve_update_version_from(target) + return unless spec + + version = spec.version + + Bundler.ui.info "Updating bundler to #{version}." + + install(spec) + + restart_with(version) + end + + private + + def install_and_restart_with(version) + requirement = Gem::Requirement.new(version) + spec = find_latest_matching_spec(requirement) + + if spec.nil? + Bundler.ui.warn "Your lockfile is locked to a version of bundler (#{lockfile_version}) that doesn't exist at https://rubygems.org/. Going on using #{current_version}" + return + end + + install(spec) + rescue StandardError => e + Bundler.ui.trace e + Bundler.ui.warn "There was an error installing the locked bundler version (#{lockfile_version}), rerun with the `--verbose` flag for more details. Going on using bundler #{current_version}." + else + restart_with(version) + end + + def install(spec) + spec.source.install(spec) + end + + def restart_with(version) + configured_gem_home = ENV["GEM_HOME"] + configured_gem_path = ENV["GEM_PATH"] + + cmd = [$PROGRAM_NAME, *ARGV] + cmd.unshift(Gem.ruby) unless File.executable?($PROGRAM_NAME) + + Bundler.with_original_env do + Kernel.exec( + { "GEM_HOME" => configured_gem_home, "GEM_PATH" => configured_gem_path, "BUNDLER_VERSION" => version.to_s }, + *cmd + ) + end + end + + def needs_switching? + autoswitching_applies? && + released?(lockfile_version) && + !running?(lockfile_version) && + !updating? + end + + def autoswitching_applies? + ENV["BUNDLER_VERSION"].nil? && + Bundler.rubygems.supports_bundler_trampolining? && + SharedHelpers.in_bundle? && + lockfile_version + end + + def resolve_update_version_from(target) + requirement = Gem::Requirement.new(target) + update_candidate = find_latest_matching_spec(requirement) + + if update_candidate.nil? + raise InvalidOption, "The `bundle update --bundler` target version (#{target}) does not exist" + end + + resolved_version = update_candidate.version + needs_update = requirement.specific? ? !running?(resolved_version) : running_older_than?(resolved_version) + + return unless needs_update + + update_candidate + end + + def local_specs + @local_specs ||= Bundler::Source::Rubygems.new("allow_local" => true).specs.select {|spec| spec.name == "bundler" } + end + + def remote_specs + @remote_specs ||= begin + source = Bundler::Source::Rubygems.new("remotes" => "https://rubygems.org") + source.remote! + source.add_dependency_names("bundler") + source.specs + end + end + + def find_latest_matching_spec(requirement) + local_result = find_latest_matching_spec_from_collection(local_specs, requirement) + return local_result if local_result && requirement.specific? + + remote_result = find_latest_matching_spec_from_collection(remote_specs, requirement) + return remote_result if local_result.nil? + + [local_result, remote_result].max + end + + def find_latest_matching_spec_from_collection(specs, requirement) + specs.sort.reverse_each.find {|spec| requirement.satisfied_by?(spec.version) } + end + + def running?(version) + version == current_version + end + + def running_older_than?(version) + current_version < version + end + + def released?(version) + !version.to_s.end_with?(".dev") + end + + def updating? + "update".start_with?(ARGV.first || " ") && ARGV[1..-1].any? {|a| a.start_with?("--bundler") } + end + + def installed? + Bundler.configure + + Bundler.rubygems.find_bundler(lockfile_version.to_s) + end + + def current_version + @current_version ||= Gem::Version.new(Bundler::VERSION) + end + + def lockfile_version + return @lockfile_version if defined?(@lockfile_version) + + parsed_version = Bundler::LockfileParser.bundled_with + @lockfile_version = parsed_version ? Gem::Version.new(parsed_version) : nil + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/settings.rb b/games/FNaFB2/Ruby/stdlib/bundler/settings.rb new file mode 100644 index 0000000..901fe26 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/settings.rb @@ -0,0 +1,513 @@ +# frozen_string_literal: true + +module Bundler + class Settings + autoload :Mirror, File.expand_path("mirror", __dir__) + autoload :Mirrors, File.expand_path("mirror", __dir__) + autoload :Validator, File.expand_path("settings/validator", __dir__) + + BOOL_KEYS = %w[ + allow_deployment_source_credential_changes + allow_offline_install + auto_clean_without_path + auto_install + cache_all + cache_all_platforms + clean + default_install_uses_path + deployment + disable_checksum_validation + disable_exec_load + disable_local_branch_check + disable_local_revision_check + disable_shared_gems + disable_version_check + force_ruby_platform + forget_cli_options + frozen + gem.changelog + gem.coc + gem.mit + git.allow_insecure + global_gem_cache + ignore_messages + init_gems_rb + inline + no_install + no_prune + path_relative_to_cwd + path.system + plugins + prefer_patch + print_only_version_number + setup_makes_kernel_gem_public + silence_deprecations + silence_root_warning + suppress_install_using_messages + update_requires_all_flag + ].freeze + + NUMBER_KEYS = %w[ + jobs + redirect + retry + ssl_verify_mode + timeout + ].freeze + + ARRAY_KEYS = %w[ + only + with + without + ].freeze + + STRING_KEYS = %w[ + bin + cache_path + console + gem.ci + gem.github_username + gem.linter + gem.rubocop + gem.test + gemfile + path + shebang + system_bindir + trust-policy + ].freeze + + DEFAULT_CONFIG = { + "BUNDLE_SILENCE_DEPRECATIONS" => false, + "BUNDLE_DISABLE_VERSION_CHECK" => true, + "BUNDLE_PREFER_PATCH" => false, + "BUNDLE_REDIRECT" => 5, + "BUNDLE_RETRY" => 3, + "BUNDLE_TIMEOUT" => 10, + }.freeze + + def initialize(root = nil) + @root = root + @local_config = load_config(local_config_file) + @env_config = ENV.to_h.select {|key, _value| key =~ /\ABUNDLE_.+/ } + @global_config = load_config(global_config_file) + @temporary = {} + end + + def [](name) + key = key_for(name) + value = configs.values.map {|config| config[key] }.compact.first + + converted_value(value, name) + end + + def set_command_option(key, value) + if Bundler.feature_flag.forget_cli_options? + temporary(key => value) + value + else + set_local(key, value) + end + end + + def set_command_option_if_given(key, value) + return if value.nil? + set_command_option(key, value) + end + + def set_local(key, value) + local_config_file || raise(GemfileNotFound, "Could not locate Gemfile") + + set_key(key, value, @local_config, local_config_file) + end + + def temporary(update) + existing = Hash[update.map {|k, _| [k, @temporary[key_for(k)]] }] + update.each do |k, v| + set_key(k, v, @temporary, nil) + end + return unless block_given? + begin + yield + ensure + existing.each {|k, v| set_key(k, v, @temporary, nil) } + end + end + + def set_global(key, value) + set_key(key, value, @global_config, global_config_file) + end + + def all + keys = @temporary.keys | @global_config.keys | @local_config.keys | @env_config.keys + + keys.map do |key| + key.sub(/^BUNDLE_/, "").gsub(/___/, "-").gsub(/__/, ".").downcase + end.sort + end + + def local_overrides + repos = {} + all.each do |k| + repos[$'] = self[k] if k =~ /^local\./ + end + repos + end + + def mirror_for(uri) + if uri.is_a?(String) + require_relative "vendored_uri" + uri = Bundler::URI(uri) + end + + gem_mirrors.for(uri.to_s).uri + end + + def credentials_for(uri) + self[uri.to_s] || self[uri.host] + end + + def gem_mirrors + all.inject(Mirrors.new) do |mirrors, k| + mirrors.parse(k, self[k]) if k.start_with?("mirror.") + mirrors + end + end + + def locations(key) + key = key_for(key) + configs.keys.inject({}) do |partial_locations, level| + value_on_level = configs[level][key] + partial_locations[level] = value_on_level unless value_on_level.nil? + partial_locations + end + end + + def pretty_values_for(exposed_key) + key = key_for(exposed_key) + + locations = [] + + if value = @temporary[key] + locations << "Set for the current command: #{printable_value(value, exposed_key).inspect}" + end + + if value = @local_config[key] + locations << "Set for your local app (#{local_config_file}): #{printable_value(value, exposed_key).inspect}" + end + + if value = @env_config[key] + locations << "Set via #{key}: #{printable_value(value, exposed_key).inspect}" + end + + if value = @global_config[key] + locations << "Set for the current user (#{global_config_file}): #{printable_value(value, exposed_key).inspect}" + end + + return ["You have not configured a value for `#{exposed_key}`"] if locations.empty? + locations + end + + def processor_count + require "etc" + Etc.nprocessors + rescue StandardError + 1 + end + + # for legacy reasons, in Bundler 2, we do not respect :disable_shared_gems + def path + configs.each do |_level, settings| + path = value_for("path", settings) + path = "vendor/bundle" if value_for("deployment", settings) && path.nil? + path_system = value_for("path.system", settings) + disabled_shared_gems = value_for("disable_shared_gems", settings) + next if path.nil? && path_system.nil? && disabled_shared_gems.nil? + system_path = path_system || (disabled_shared_gems == false) + return Path.new(path, system_path) + end + + Path.new(nil, false) + end + + Path = Struct.new(:explicit_path, :system_path) do + def path + path = base_path + path = File.join(path, Bundler.ruby_scope) unless use_system_gems? + path + end + + def use_system_gems? + return true if system_path + return false if explicit_path + !Bundler.feature_flag.default_install_uses_path? + end + + def base_path + path = explicit_path + path ||= ".bundle" unless use_system_gems? + path ||= Bundler.rubygems.gem_dir + path + end + + def base_path_relative_to_pwd + base_path = Pathname.new(self.base_path) + expanded_base_path = base_path.expand_path(Bundler.root) + relative_path = expanded_base_path.relative_path_from(Pathname.pwd) + if relative_path.to_s.start_with?("..") + relative_path = base_path if base_path.absolute? + else + relative_path = Pathname.new(File.join(".", relative_path)) + end + relative_path + rescue ArgumentError + expanded_base_path + end + + def validate! + return unless explicit_path && system_path + path = Bundler.settings.pretty_values_for(:path) + path.unshift(nil, "path:") unless path.empty? + system_path = Bundler.settings.pretty_values_for("path.system") + system_path.unshift(nil, "path.system:") unless system_path.empty? + disable_shared_gems = Bundler.settings.pretty_values_for(:disable_shared_gems) + disable_shared_gems.unshift(nil, "disable_shared_gems:") unless disable_shared_gems.empty? + raise InvalidOption, + "Using a custom path while using system gems is unsupported.\n#{path.join("\n")}\n#{system_path.join("\n")}\n#{disable_shared_gems.join("\n")}" + end + end + + def allow_sudo? + key = key_for(:path) + path_configured = @temporary.key?(key) || @local_config.key?(key) + !path_configured + end + + def ignore_config? + ENV["BUNDLE_IGNORE_CONFIG"] + end + + def app_cache_path + @app_cache_path ||= self[:cache_path] || "vendor/cache" + end + + def validate! + all.each do |raw_key| + [@local_config, @env_config, @global_config].each do |settings| + value = value_for(raw_key, settings) + Validator.validate!(raw_key, value, settings.dup) + end + end + end + + def key_for(key) + self.class.key_for(key) + end + + private + + def configs + { + :temporary => @temporary, + :local => @local_config, + :env => @env_config, + :global => @global_config, + :default => DEFAULT_CONFIG, + } + end + + def value_for(name, config) + converted_value(config[key_for(name)], name) + end + + def parent_setting_for(name) + split_specific_setting_for(name)[0] + end + + def specific_gem_for(name) + split_specific_setting_for(name)[1] + end + + def split_specific_setting_for(name) + name.split(".") + end + + def is_bool(name) + BOOL_KEYS.include?(name.to_s) || BOOL_KEYS.include?(parent_setting_for(name.to_s)) + end + + def is_string(name) + STRING_KEYS.include?(name.to_s) || name.to_s.start_with?("local.") || name.to_s.start_with?("mirror.") || name.to_s.start_with?("build.") + end + + def to_bool(value) + case value + when nil, /\A(false|f|no|n|0|)\z/i, false + false + else + true + end + end + + def is_num(key) + NUMBER_KEYS.include?(key.to_s) + end + + def is_array(key) + ARRAY_KEYS.include?(key.to_s) + end + + def is_credential(key) + key == "gem.push_key" + end + + def is_userinfo(value) + value.include?(":") + end + + def to_array(value) + return [] unless value + value.tr(" ", ":").split(":").map(&:to_sym) + end + + def array_to_s(array) + array = Array(array) + return nil if array.empty? + array.join(":").tr(" ", ":") + end + + def set_key(raw_key, value, hash, file) + raw_key = raw_key.to_s + value = array_to_s(value) if is_array(raw_key) + + key = key_for(raw_key) + + return if hash[key] == value + + hash[key] = value + hash.delete(key) if value.nil? + + Validator.validate!(raw_key, converted_value(value, raw_key), hash) + + return unless file + SharedHelpers.filesystem_access(file) do |p| + FileUtils.mkdir_p(p.dirname) + require_relative "yaml_serializer" + p.open("w") {|f| f.write(YAMLSerializer.dump(hash)) } + end + end + + def converted_value(value, key) + if is_array(key) + to_array(value) + elsif value.nil? + nil + elsif is_bool(key) || value == "false" + to_bool(value) + elsif is_num(key) + value.to_i + else + value.to_s + end + end + + def printable_value(value, key) + converted = converted_value(value, key) + return converted unless converted.is_a?(String) + + if is_string(key) + converted + elsif is_credential(key) + "[REDACTED]" + elsif is_userinfo(converted) + username, pass = converted.split(":", 2) + + if pass == "x-oauth-basic" + username = "[REDACTED]" + else + pass = "[REDACTED]" + end + + [username, pass].join(":") + else + converted + end + end + + def global_config_file + if ENV["BUNDLE_CONFIG"] && !ENV["BUNDLE_CONFIG"].empty? + Pathname.new(ENV["BUNDLE_CONFIG"]) + elsif ENV["BUNDLE_USER_CONFIG"] && !ENV["BUNDLE_USER_CONFIG"].empty? + Pathname.new(ENV["BUNDLE_USER_CONFIG"]) + elsif ENV["BUNDLE_USER_HOME"] && !ENV["BUNDLE_USER_HOME"].empty? + Pathname.new(ENV["BUNDLE_USER_HOME"]).join("config") + elsif Bundler.rubygems.user_home && !Bundler.rubygems.user_home.empty? + Pathname.new(Bundler.rubygems.user_home).join(".bundle/config") + end + end + + def local_config_file + Pathname.new(@root).join("config") if @root + end + + def load_config(config_file) + return {} if !config_file || ignore_config? + SharedHelpers.filesystem_access(config_file, :read) do |file| + valid_file = file.exist? && !file.size.zero? + return {} unless valid_file + require_relative "yaml_serializer" + YAMLSerializer.load(file.read).inject({}) do |config, (k, v)| + new_k = k + + if k.include?("-") + Bundler.ui.warn "Your #{file} config includes `#{k}`, which contains the dash character (`-`).\n" \ + "This is deprecated, because configuration through `ENV` should be possible, but `ENV` keys cannot include dashes.\n" \ + "Please edit #{file} and replace any dashes in configuration keys with a triple underscore (`___`)." + + new_k = k.gsub("-", "___") + end + + config[new_k] = v + config + end + end + end + + PER_URI_OPTIONS = %w[ + fallback_timeout + ].freeze + + NORMALIZE_URI_OPTIONS_PATTERN = + / + \A + (\w+\.)? # optional prefix key + (https?.*?) # URI + (\.#{Regexp.union(PER_URI_OPTIONS)})? # optional suffix key + \z + /ix.freeze + + def self.key_for(key) + key = normalize_uri(key).to_s if key.is_a?(String) && key.start_with?("http", "mirror.http") + key = key.to_s.gsub(".", "__").gsub("-", "___").upcase + "BUNDLE_#{key}" + end + + # TODO: duplicates Rubygems#normalize_uri + # TODO: is this the correct place to validate mirror URIs? + def self.normalize_uri(uri) + uri = uri.to_s + if uri =~ NORMALIZE_URI_OPTIONS_PATTERN + prefix = $1 + uri = $2 + suffix = $3 + end + uri = "#{uri}/" unless uri.end_with?("/") + require_relative "vendored_uri" + uri = Bundler::URI(uri) + unless uri.absolute? + raise ArgumentError, format("Gem sources must be absolute. You provided '%s'.", uri) + end + "#{prefix}#{uri}#{suffix}" + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/settings/validator.rb b/games/FNaFB2/Ruby/stdlib/bundler/settings/validator.rb new file mode 100644 index 0000000..0a57ea7 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/settings/validator.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +module Bundler + class Settings + class Validator + class Rule + attr_reader :description + + def initialize(keys, description, &validate) + @keys = keys + @description = description + @validate = validate + end + + def validate!(key, value, settings) + instance_exec(key, value, settings, &@validate) + end + + def fail!(key, value, *reasons) + reasons.unshift @description + raise InvalidOption, "Setting `#{key}` to #{value.inspect} failed:\n#{reasons.map {|r| " - #{r}" }.join("\n")}" + end + + def set(settings, key, value, *reasons) + hash_key = k(key) + return if settings[hash_key] == value + reasons.unshift @description + Bundler.ui.info "Setting `#{key}` to #{value.inspect}, since #{reasons.join(", ")}" + if value.nil? + settings.delete(hash_key) + else + settings[hash_key] = value + end + end + + def k(key) + Bundler.settings.key_for(key) + end + end + + def self.rules + @rules ||= Hash.new {|h, k| h[k] = [] } + end + private_class_method :rules + + def self.rule(keys, description, &blk) + rule = Rule.new(keys, description, &blk) + keys.each {|k| rules[k] << rule } + end + private_class_method :rule + + def self.validate!(key, value, settings) + rules_to_validate = rules[key] + rules_to_validate.each {|rule| rule.validate!(key, value, settings) } + end + + rule %w[path path.system], "path and path.system are mutually exclusive" do |key, value, settings| + if key == "path" && value + set(settings, "path.system", nil) + elsif key == "path.system" && value + set(settings, :path, nil) + end + end + + rule %w[with without], "a group cannot be in both `with` & `without` simultaneously" do |key, value, settings| + with = settings.fetch(k(:with), "").split(":").map(&:to_sym) + without = settings.fetch(k(:without), "").split(":").map(&:to_sym) + + other_key = key == "with" ? :without : :with + other_setting = key == "with" ? without : with + + conflicting = with & without + if conflicting.any? + fail!(key, value, "`#{other_key}` is current set to #{other_setting.inspect}", "the `#{conflicting.join("`, `")}` groups conflict") + end + end + + rule %w[path], "relative paths are expanded relative to the current working directory" do |key, value, settings| + next if value.nil? + + path = Pathname.new(value) + next if !path.relative? || !Bundler.feature_flag.path_relative_to_cwd? + + path = path.expand_path + + root = begin + Bundler.root + rescue GemfileNotFound + Pathname.pwd.expand_path + end + + path = begin + path.relative_path_from(root) + rescue ArgumentError + path + end + + set(settings, key, path.to_s) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/setup.rb b/games/FNaFB2/Ruby/stdlib/bundler/setup.rb new file mode 100644 index 0000000..32e9b2d --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/setup.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require_relative "shared_helpers" + +if Bundler::SharedHelpers.in_bundle? + require_relative "../bundler" + + if STDOUT.tty? || ENV["BUNDLER_FORCE_TTY"] + begin + Bundler.ui.silence { Bundler.setup } + rescue Bundler::BundlerError => e + Bundler.ui.error e.message + Bundler.ui.warn e.backtrace.join("\n") if ENV["DEBUG"] + if e.is_a?(Bundler::GemNotFound) + Bundler.ui.warn "Run `bundle install` to install missing gems." + end + exit e.status_code + end + else + Bundler.ui.silence { Bundler.setup } + end + + # We might be in the middle of shelling out to rubygems + # (RUBYOPT=-rbundler/setup), so we need to give rubygems the opportunity of + # not being silent. + Gem::DefaultUserInteraction.ui = nil +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/shared_helpers.rb b/games/FNaFB2/Ruby/stdlib/bundler/shared_helpers.rb new file mode 100644 index 0000000..899eb68 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/shared_helpers.rb @@ -0,0 +1,342 @@ +# frozen_string_literal: true + +require "pathname" +require "rbconfig" + +require_relative "version" +require_relative "constants" +require_relative "rubygems_integration" +require_relative "current_ruby" + +module Bundler + module SharedHelpers + def root + gemfile = find_gemfile + raise GemfileNotFound, "Could not locate Gemfile" unless gemfile + Pathname.new(gemfile).tap {|x| x.untaint if RUBY_VERSION < "2.7" }.expand_path.parent + end + + def default_gemfile + gemfile = find_gemfile + raise GemfileNotFound, "Could not locate Gemfile" unless gemfile + Pathname.new(gemfile).tap {|x| x.untaint if RUBY_VERSION < "2.7" }.expand_path + end + + def default_lockfile + gemfile = default_gemfile + + case gemfile.basename.to_s + when "gems.rb" then Pathname.new(gemfile.sub(/.rb$/, ".locked")) + else Pathname.new("#{gemfile}.lock") + end.tap {|x| x.untaint if RUBY_VERSION < "2.7" } + end + + def default_bundle_dir + bundle_dir = find_directory(".bundle") + return nil unless bundle_dir + + bundle_dir = Pathname.new(bundle_dir) + + global_bundle_dir = Bundler.user_home.join(".bundle") + return nil if bundle_dir == global_bundle_dir + + bundle_dir + end + + def in_bundle? + find_gemfile + end + + def chdir(dir, &blk) + Bundler.rubygems.ext_lock.synchronize do + Dir.chdir dir, &blk + end + end + + def pwd + Bundler.rubygems.ext_lock.synchronize do + Pathname.pwd + end + end + + def with_clean_git_env(&block) + keys = %w[GIT_DIR GIT_WORK_TREE] + old_env = keys.inject({}) do |h, k| + h.update(k => ENV[k]) + end + + keys.each {|key| ENV.delete(key) } + + block.call + ensure + keys.each {|key| ENV[key] = old_env[key] } + end + + def set_bundle_environment + set_bundle_variables + set_path + set_rubyopt + set_rubylib + end + + # Rescues permissions errors raised by file system operations + # (ie. Errno:EACCESS, Errno::EAGAIN) and raises more friendly errors instead. + # + # @param path [String] the path that the action will be attempted to + # @param action [Symbol, #to_s] the type of operation that will be + # performed. For example: :write, :read, :exec + # + # @yield path + # + # @raise [Bundler::PermissionError] if Errno:EACCES is raised in the + # given block + # @raise [Bundler::TemporaryResourceError] if Errno:EAGAIN is raised in the + # given block + # + # @example + # filesystem_access("vendor/cache", :write) do + # FileUtils.mkdir_p("vendor/cache") + # end + # + # @see {Bundler::PermissionError} + def filesystem_access(path, action = :write, &block) + yield(path.dup.tap {|x| x.untaint if RUBY_VERSION < "2.7" }) + rescue Errno::EACCES + raise PermissionError.new(path, action) + rescue Errno::EAGAIN + raise TemporaryResourceError.new(path, action) + rescue Errno::EPROTO + raise VirtualProtocolError.new + rescue Errno::ENOSPC + raise NoSpaceOnDeviceError.new(path, action) + rescue Errno::ENOTSUP + raise OperationNotSupportedError.new(path, action) + rescue Errno::EEXIST, Errno::ENOENT + raise + rescue SystemCallError => e + raise GenericSystemCallError.new(e, "There was an error accessing `#{path}`.") + end + + def major_deprecation(major_version, message, print_caller_location: false) + if print_caller_location + caller_location = caller_locations(2, 2).first + message = "#{message} (called at #{caller_location.path}:#{caller_location.lineno})" + end + + bundler_major_version = Bundler.bundler_major_version + if bundler_major_version > major_version + require_relative "errors" + raise DeprecatedError, "[REMOVED] #{message}" + end + + return unless bundler_major_version >= major_version && prints_major_deprecations? + Bundler.ui.warn("[DEPRECATED] #{message}") + end + + def print_major_deprecations! + multiple_gemfiles = search_up(".") do |dir| + gemfiles = gemfile_names.select {|gf| File.file? File.expand_path(gf, dir) } + next if gemfiles.empty? + break gemfiles.size != 1 + end + return unless multiple_gemfiles + message = "Multiple gemfiles (gems.rb and Gemfile) detected. " \ + "Make sure you remove Gemfile and Gemfile.lock since bundler is ignoring them in favor of gems.rb and gems.locked." + Bundler.ui.warn message + end + + def ensure_same_dependencies(spec, old_deps, new_deps) + new_deps = new_deps.reject {|d| d.type == :development } + old_deps = old_deps.reject {|d| d.type == :development } + + without_type = proc {|d| Gem::Dependency.new(d.name, d.requirements_list.sort) } + new_deps.map!(&without_type) + old_deps.map!(&without_type) + + extra_deps = new_deps - old_deps + return if extra_deps.empty? + + Bundler.ui.debug "#{spec.full_name} from #{spec.remote} has either corrupted API or lockfile dependencies" \ + " (was expecting #{old_deps.map(&:to_s)}, but the real spec has #{new_deps.map(&:to_s)})" + raise APIResponseMismatchError, + "Downloading #{spec.full_name} revealed dependencies not in the API or the lockfile (#{extra_deps.join(", ")})." \ + "\nEither installing with `--full-index` or running `bundle update #{spec.name}` should fix the problem." + end + + def pretty_dependency(dep) + msg = String.new(dep.name) + msg << " (#{dep.requirement})" unless dep.requirement == Gem::Requirement.default + + if dep.is_a?(Bundler::Dependency) + platform_string = dep.platforms.join(", ") + msg << " " << platform_string if !platform_string.empty? && platform_string != Gem::Platform::RUBY + end + + msg + end + + def md5_available? + return @md5_available if defined?(@md5_available) + @md5_available = begin + require "openssl" + ::OpenSSL::Digest.digest("MD5", "") + true + rescue LoadError + true + rescue ::OpenSSL::Digest::DigestError + false + end + end + + def digest(name) + require "digest" + Digest(name) + end + + def write_to_gemfile(gemfile_path, contents) + filesystem_access(gemfile_path) {|g| File.open(g, "w") {|file| file.puts contents } } + end + + private + + def validate_bundle_path + path_separator = Bundler.rubygems.path_separator + return unless Bundler.bundle_path.to_s.split(path_separator).size > 1 + message = "Your bundle path contains text matching #{path_separator.inspect}, " \ + "which is the path separator for your system. Bundler cannot " \ + "function correctly when the Bundle path contains the " \ + "system's PATH separator. Please change your " \ + "bundle path to not match #{path_separator.inspect}." \ + "\nYour current bundle path is '#{Bundler.bundle_path}'." + raise Bundler::PathError, message + end + + def find_gemfile + given = ENV["BUNDLE_GEMFILE"] + return given if given && !given.empty? + find_file(*gemfile_names) + end + + def gemfile_names + ["gems.rb", "Gemfile"] + end + + def find_file(*names) + search_up(*names) do |filename| + return filename if File.file?(filename) + end + end + + def find_directory(*names) + search_up(*names) do |dirname| + return dirname if File.directory?(dirname) + end + end + + def search_up(*names) + previous = nil + current = File.expand_path(SharedHelpers.pwd).tap {|x| x.untaint if RUBY_VERSION < "2.7" } + + until !File.directory?(current) || current == previous + if ENV["BUNDLER_SPEC_RUN"] + # avoid stepping above the tmp directory when testing + gemspec = if ENV["GEM_COMMAND"] + # for Ruby Core + "lib/bundler/bundler.gemspec" + else + "bundler.gemspec" + end + + # avoid stepping above the tmp directory when testing + return nil if File.file?(File.join(current, gemspec)) + end + + names.each do |name| + filename = File.join(current, name) + yield filename + end + previous = current + current = File.expand_path("..", current) + end + end + + def set_env(key, value) + raise ArgumentError, "new key #{key}" unless EnvironmentPreserver::BUNDLER_KEYS.include?(key) + orig_key = "#{EnvironmentPreserver::BUNDLER_PREFIX}#{key}" + orig = ENV[key] + orig ||= EnvironmentPreserver::INTENTIONALLY_NIL + ENV[orig_key] ||= orig + + ENV[key] = value + end + public :set_env + + def set_bundle_variables + # bundler exe & lib folders have same root folder, typical gem installation + exe_file = File.expand_path("../../exe/bundle", __dir__) + + # for Ruby core repository testing + exe_file = File.expand_path("../../libexec/bundle", __dir__) unless File.exist?(exe_file) + + # bundler is a default gem, exe path is separate + exe_file = Bundler.rubygems.bin_path("bundler", "bundle", VERSION) unless File.exist?(exe_file) + + Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", exe_file + Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile.to_s + Bundler::SharedHelpers.set_env "BUNDLER_VERSION", Bundler::VERSION + end + + def set_path + validate_bundle_path + paths = (ENV["PATH"] || "").split(File::PATH_SEPARATOR) + paths.unshift "#{Bundler.bundle_path}/bin" + Bundler::SharedHelpers.set_env "PATH", paths.uniq.join(File::PATH_SEPARATOR) + end + + def set_rubyopt + rubyopt = [ENV["RUBYOPT"]].compact + setup_require = "-r#{File.expand_path("setup", __dir__)}" + return if !rubyopt.empty? && rubyopt.first =~ /#{setup_require}/ + rubyopt.unshift setup_require + Bundler::SharedHelpers.set_env "RUBYOPT", rubyopt.join(" ") + end + + def set_rubylib + rubylib = (ENV["RUBYLIB"] || "").split(File::PATH_SEPARATOR) + rubylib.unshift bundler_ruby_lib unless RbConfig::CONFIG["rubylibdir"] == bundler_ruby_lib + Bundler::SharedHelpers.set_env "RUBYLIB", rubylib.uniq.join(File::PATH_SEPARATOR) + end + + def bundler_ruby_lib + File.expand_path("..", __dir__) + end + + def clean_load_path + loaded_gem_paths = Bundler.rubygems.loaded_gem_paths + + $LOAD_PATH.reject! do |p| + resolved_path = resolve_path(p) + next if $LOADED_FEATURES.any? {|lf| lf.start_with?(resolved_path) } + loaded_gem_paths.delete(p) + end + $LOAD_PATH.uniq! + end + + def resolve_path(path) + expanded = File.expand_path(path) + return expanded unless File.exist?(expanded) + + File.realpath(expanded) + end + + def prints_major_deprecations? + require_relative "../bundler" + return false if Bundler.settings[:silence_deprecations] + require_relative "deprecate" + return false if Bundler::Deprecate.skip + true + end + + extend self + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/similarity_detector.rb b/games/FNaFB2/Ruby/stdlib/bundler/similarity_detector.rb new file mode 100644 index 0000000..50e66b9 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/similarity_detector.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module Bundler + class SimilarityDetector + SimilarityScore = Struct.new(:string, :distance) + + # initialize with an array of words to be matched against + def initialize(corpus) + @corpus = corpus + end + + # return an array of words similar to 'word' from the corpus + def similar_words(word, limit = 3) + words_by_similarity = @corpus.map {|w| SimilarityScore.new(w, levenshtein_distance(word, w)) } + words_by_similarity.select {|s| s.distance <= limit }.sort_by(&:distance).map(&:string) + end + + # return the result of 'similar_words', concatenated into a list + # (eg "a, b, or c") + def similar_word_list(word, limit = 3) + words = similar_words(word, limit) + if words.length == 1 + words[0] + elsif words.length > 1 + [words[0..-2].join(", "), words[-1]].join(" or ") + end + end + + protected + + # https://www.informit.com/articles/article.aspx?p=683059&seqNum=36 + def levenshtein_distance(this, that, ins = 2, del = 2, sub = 1) + # ins, del, sub are weighted costs + return nil if this.nil? + return nil if that.nil? + dm = [] # distance matrix + + # Initialize first row values + dm[0] = (0..this.length).collect {|i| i * ins } + fill = [0] * (this.length - 1) + + # Initialize first column values + (1..that.length).each do |i| + dm[i] = [i * del, fill.flatten] + end + + # populate matrix + (1..that.length).each do |i| + (1..this.length).each do |j| + # critical comparison + dm[i][j] = [ + dm[i - 1][j - 1] + (this[j - 1] == that[i - 1] ? 0 : sub), + dm[i][j - 1] + ins, + dm[i - 1][j] + del, + ].min + end + end + + # The last value in matrix is the Levenshtein distance between the strings + dm[that.length][this.length] + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/source.rb b/games/FNaFB2/Ruby/stdlib/bundler/source.rb new file mode 100644 index 0000000..69804a2 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/source.rb @@ -0,0 +1,114 @@ +# frozen_string_literal: true + +module Bundler + class Source + autoload :Gemspec, File.expand_path("source/gemspec", __dir__) + autoload :Git, File.expand_path("source/git", __dir__) + autoload :Metadata, File.expand_path("source/metadata", __dir__) + autoload :Path, File.expand_path("source/path", __dir__) + autoload :Rubygems, File.expand_path("source/rubygems", __dir__) + autoload :RubygemsAggregate, File.expand_path("source/rubygems_aggregate", __dir__) + + attr_accessor :dependency_names + + def unmet_deps + specs.unmet_dependency_names + end + + def version_message(spec, locked_spec = nil) + message = "#{spec.name} #{spec.version}" + message += " (#{spec.platform})" if spec.platform != Gem::Platform::RUBY && !spec.platform.nil? + + if locked_spec + locked_spec_version = locked_spec.version + if locked_spec_version && spec.version != locked_spec_version + message += Bundler.ui.add_color(" (was #{locked_spec_version})", version_color(spec.version, locked_spec_version)) + end + end + + message + end + + def can_lock?(spec) + spec.source == self + end + + def local!; end + + def local_only!; end + + def cached!; end + + def remote!; end + + def add_dependency_names(names) + @dependency_names = Array(dependency_names) | Array(names) + end + + # it's possible that gems from one source depend on gems from some + # other source, so now we download gemspecs and iterate over those + # dependencies, looking for gems we don't have info on yet. + def double_check_for(*); end + + def dependency_names_to_double_check + specs.dependency_names + end + + def spec_names + specs.spec_names + end + + def include?(other) + other == self + end + + def inspect + "#<#{self.class}:0x#{object_id} #{self}>" + end + + def identifier + to_s + end + + def path? + instance_of?(Bundler::Source::Path) + end + + def extension_cache_path(spec) + return unless Bundler.feature_flag.global_gem_cache? + return unless source_slug = extension_cache_slug(spec) + Bundler.user_cache.join( + "extensions", Gem::Platform.local.to_s, Bundler.ruby_scope, + source_slug, spec.full_name + ) + end + + private + + def version_color(spec_version, locked_spec_version) + if Gem::Version.correct?(spec_version) && Gem::Version.correct?(locked_spec_version) + # display yellow if there appears to be a regression + earlier_version?(spec_version, locked_spec_version) ? :yellow : :green + else + # default to green if the versions cannot be directly compared + :green + end + end + + def earlier_version?(spec_version, locked_spec_version) + Gem::Version.new(spec_version) < Gem::Version.new(locked_spec_version) + end + + def print_using_message(message) + if !message.include?("(was ") && Bundler.feature_flag.suppress_install_using_messages? + Bundler.ui.debug message + else + Bundler.ui.info message + end + end + + def extension_cache_slug(_) + nil + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/source/gemspec.rb b/games/FNaFB2/Ruby/stdlib/bundler/source/gemspec.rb new file mode 100644 index 0000000..7e3447e --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/source/gemspec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Bundler + class Source + class Gemspec < Path + attr_reader :gemspec + + def initialize(options) + super + @gemspec = options["gemspec"] + end + + def as_path_source + Path.new(options) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/source/git.rb b/games/FNaFB2/Ruby/stdlib/bundler/source/git.rb new file mode 100644 index 0000000..ed66dcd --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/source/git.rb @@ -0,0 +1,354 @@ +# frozen_string_literal: true + +require_relative "../vendored_fileutils" + +module Bundler + class Source + class Git < Path + autoload :GitProxy, File.expand_path("git/git_proxy", __dir__) + + attr_reader :uri, :ref, :branch, :options, :glob, :submodules + + def initialize(options) + @options = options + @glob = options["glob"] || DEFAULT_GLOB + + @allow_cached = false + @allow_remote = false + + # Stringify options that could be set as symbols + %w[ref branch tag revision].each {|k| options[k] = options[k].to_s if options[k] } + + @uri = options["uri"] || "" + @safe_uri = URICredentialsFilter.credential_filtered_uri(@uri) + @branch = options["branch"] + @ref = options["ref"] || options["branch"] || options["tag"] + @submodules = options["submodules"] + @name = options["name"] + @version = options["version"].to_s.strip.gsub("-", ".pre.") + + @copied = false + @local = false + end + + def self.from_lock(options) + new(options.merge("uri" => options.delete("remote"))) + end + + def to_lock + out = String.new("GIT\n") + out << " remote: #{@uri}\n" + out << " revision: #{revision}\n" + %w[ref branch tag submodules].each do |opt| + out << " #{opt}: #{options[opt]}\n" if options[opt] + end + out << " glob: #{@glob}\n" unless default_glob? + out << " specs:\n" + end + + def hash + [self.class, uri, ref, branch, name, version, glob, submodules].hash + end + + def eql?(other) + other.is_a?(Git) && uri == other.uri && ref == other.ref && + branch == other.branch && name == other.name && + version == other.version && glob == other.glob && + submodules == other.submodules + end + + alias_method :==, :eql? + + def to_s + begin + at = if local? + path + elsif user_ref = options["ref"] + if ref =~ /\A[a-z0-9]{4,}\z/i + shortref_for_display(user_ref) + else + user_ref + end + elsif ref + ref + else + git_proxy.branch + end + + rev = "at #{at}@#{shortref_for_display(revision)}" + rescue GitError + "" + end + + specifiers = [rev, glob_for_display].compact + suffix = + if specifiers.any? + " (#{specifiers.join(", ")})" + else + "" + end + + "#{@safe_uri}#{suffix}" + end + + def name + File.basename(@uri, ".git") + end + + # This is the path which is going to contain a specific + # checkout of the git repository. When using local git + # repos, this is set to the local repo. + def install_path + @install_path ||= begin + git_scope = "#{base_name}-#{shortref_for_path(revision)}" + + path = Bundler.install_path.join(git_scope) + + if !path.exist? && Bundler.requires_sudo? + Bundler.user_bundle_path.join(Bundler.ruby_scope).join(git_scope) + else + path + end + end + end + + alias_method :path, :install_path + + def extension_dir_name + "#{base_name}-#{shortref_for_path(revision)}" + end + + def unlock! + git_proxy.revision = nil + options["revision"] = nil + + @unlocked = true + end + + def local_override!(path) + return false if local? + + original_path = path + path = Pathname.new(path) + path = path.expand_path(Bundler.root) unless path.relative? + + unless options["branch"] || Bundler.settings[:disable_local_branch_check] + raise GitError, "Cannot use local override for #{name} at #{path} because " \ + ":branch is not specified in Gemfile. Specify a branch or run " \ + "`bundle config unset local.#{override_for(original_path)}` to remove the local override" + end + + unless path.exist? + raise GitError, "Cannot use local override for #{name} because #{path} " \ + "does not exist. Run `bundle config unset local.#{override_for(original_path)}` to remove the local override" + end + + set_local!(path) + + # Create a new git proxy without the cached revision + # so the Gemfile.lock always picks up the new revision. + @git_proxy = GitProxy.new(path, uri, ref) + + if git_proxy.branch != options["branch"] && !Bundler.settings[:disable_local_branch_check] + raise GitError, "Local override for #{name} at #{path} is using branch " \ + "#{git_proxy.branch} but Gemfile specifies #{options["branch"]}" + end + + changed = cached_revision && cached_revision != git_proxy.revision + + if !Bundler.settings[:disable_local_revision_check] && changed && !@unlocked && !git_proxy.contains?(cached_revision) + raise GitError, "The Gemfile lock is pointing to revision #{shortref_for_display(cached_revision)} " \ + "but the current branch in your local override for #{name} does not contain such commit. " \ + "Please make sure your branch is up to date." + end + + changed + end + + def specs(*) + set_local!(app_cache_path) if has_app_cache? && !local? + + if requires_checkout? && !@copied + fetch + git_proxy.copy_to(install_path, submodules) + serialize_gemspecs_in(install_path) + @copied = true + end + + local_specs + end + + def install(spec, options = {}) + force = options[:force] + + print_using_message "Using #{version_message(spec, options[:previous_spec])} from #{self}" + + if (requires_checkout? && !@copied) || force + Bundler.ui.debug " * Checking out revision: #{ref}" + git_proxy.copy_to(install_path, submodules) + serialize_gemspecs_in(install_path) + @copied = true + end + + generate_bin_options = { :disable_extensions => !Bundler.rubygems.spec_missing_extensions?(spec), :build_args => options[:build_args] } + generate_bin(spec, generate_bin_options) + + requires_checkout? ? spec.post_install_message : nil + end + + def cache(spec, custom_path = nil) + app_cache_path = app_cache_path(custom_path) + return unless Bundler.feature_flag.cache_all? + return if path == app_cache_path + cached! + FileUtils.rm_rf(app_cache_path) + git_proxy.checkout if requires_checkout? + git_proxy.copy_to(app_cache_path, @submodules) + serialize_gemspecs_in(app_cache_path) + end + + def load_spec_files + super + rescue PathError => e + Bundler.ui.trace e + raise GitError, "#{self} is not yet checked out. Run `bundle install` first." + end + + # This is the path which is going to contain a cache + # of the git repository. When using the same git repository + # across different projects, this cache will be shared. + # When using local git repos, this is set to the local repo. + def cache_path + @cache_path ||= if Bundler.requires_sudo? || Bundler.feature_flag.global_gem_cache? + Bundler.user_cache + else + Bundler.bundle_path.join("cache", "bundler") + end.join("git", git_scope) + end + + def app_cache_dirname + "#{base_name}-#{shortref_for_path(cached_revision || revision)}" + end + + def revision + git_proxy.revision + end + + def allow_git_ops? + @allow_remote || @allow_cached + end + + def local? + @local + end + + private + + def serialize_gemspecs_in(destination) + destination = destination.expand_path(Bundler.root) if destination.relative? + Dir["#{destination}/#{@glob}"].each do |spec_path| + # Evaluate gemspecs and cache the result. Gemspecs + # in git might require git or other dependencies. + # The gemspecs we cache should already be evaluated. + spec = Bundler.load_gemspec(spec_path) + next unless spec + Bundler.rubygems.set_installed_by_version(spec) + Bundler.rubygems.validate(spec) + File.open(spec_path, "wb") {|file| file.write(spec.to_ruby) } + end + end + + def set_local!(path) + @local = true + @local_specs = @git_proxy = nil + @cache_path = @install_path = path + end + + def has_app_cache? + cached_revision && super + end + + def requires_checkout? + allow_git_ops? && !local? && !cached_revision_checked_out? + end + + def cached_revision_checked_out? + cached_revision && cached_revision == revision && install_path.exist? + end + + def base_name + File.basename(uri.sub(%r{^(\w+://)?([^/:]+:)?(//\w*/)?(\w*/)*}, ""), ".git") + end + + def shortref_for_display(ref) + ref[0..6] + end + + def shortref_for_path(ref) + ref[0..11] + end + + def glob_for_display + default_glob? ? nil : "glob: #{@glob}" + end + + def default_glob? + @glob == DEFAULT_GLOB + end + + def uri_hash + if uri =~ %r{^\w+://(\w+@)?} + # Downcase the domain component of the URI + # and strip off a trailing slash, if one is present + input = Bundler::URI.parse(uri).normalize.to_s.sub(%r{/$}, "") + else + # If there is no URI scheme, assume it is an ssh/git URI + input = uri + end + # We use SHA1 here for historical reason and to preserve backward compatibility. + # But a transition to a simpler mangling algorithm would be welcome. + Bundler::Digest.sha1(input) + end + + def cached_revision + options["revision"] + end + + def cached? + cache_path.exist? + end + + def git_proxy + @git_proxy ||= GitProxy.new(cache_path, uri, ref, cached_revision, self) + end + + def fetch + git_proxy.checkout + rescue GitError => e + raise unless Bundler.feature_flag.allow_offline_install? + Bundler.ui.warn "Using cached git data because of network errors:\n#{e}" + end + + # no-op, since we validate when re-serializing the gemspec + def validate_spec(_spec); end + + def load_gemspec(file) + stub = Gem::StubSpecification.gemspec_stub(file, install_path.parent, install_path.parent) + stub.full_gem_path = Pathname.new(file).dirname.expand_path(root).to_s.tap {|x| x.untaint if RUBY_VERSION < "2.7" } + StubSpecification.from_stub(stub) + end + + def git_scope + "#{base_name}-#{uri_hash}" + end + + def extension_cache_slug(_) + extension_dir_name + end + + def override_for(path) + Bundler.settings.local_overrides.key(path) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/source/git/git_proxy.rb b/games/FNaFB2/Ruby/stdlib/bundler/source/git/git_proxy.rb new file mode 100644 index 0000000..745a7fe --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/source/git/git_proxy.rb @@ -0,0 +1,263 @@ +# frozen_string_literal: true + +module Bundler + class Source + class Git + class GitNotInstalledError < GitError + def initialize + msg = String.new + msg << "You need to install git to be able to use gems from git repositories. " + msg << "For help installing git, please refer to GitHub's tutorial at https://help.github.com/articles/set-up-git" + super msg + end + end + + class GitNotAllowedError < GitError + def initialize(command) + msg = String.new + msg << "Bundler is trying to run `#{command}` at runtime. You probably need to run `bundle install`. However, " + msg << "this error message could probably be more useful. Please submit a ticket at https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md " + msg << "with steps to reproduce as well as the following\n\nCALLER: #{caller.join("\n")}" + super msg + end + end + + class GitCommandError < GitError + attr_reader :command + + def initialize(command, path, extra_info = nil) + @command = command + + msg = String.new + msg << "Git error: command `#{command}` in directory #{path} has failed." + msg << "\n#{extra_info}" if extra_info + msg << "\nIf this error persists you could try removing the cache directory '#{path}'" if path.exist? + super msg + end + end + + class MissingGitRevisionError < GitCommandError + def initialize(command, destination_path, ref, repo) + msg = "Revision #{ref} does not exist in the repository #{repo}. Maybe you misspelled it?" + super command, destination_path, msg + end + end + + # The GitProxy is responsible to interact with git repositories. + # All actions required by the Git source is encapsulated in this + # object. + class GitProxy + attr_accessor :path, :uri, :ref + attr_writer :revision + + def initialize(path, uri, ref, revision = nil, git = nil) + @path = path + @uri = uri + @ref = ref + @revision = revision + @git = git + end + + def revision + @revision ||= find_local_revision + end + + def branch + @branch ||= allowed_with_path do + git("rev-parse", "--abbrev-ref", "HEAD", :dir => path).strip + end + end + + def contains?(commit) + allowed_with_path do + result, status = git_null("branch", "--contains", commit, :dir => path) + status.success? && result =~ /^\* (.*)$/ + end + end + + def version + git("--version").match(/(git version\s*)?((\.?\d+)+).*/)[2] + end + + def full_version + git("--version").sub("git version", "").strip + end + + def checkout + return if path.exist? && has_revision_cached? + extra_ref = "#{ref}:#{ref}" if ref && ref.start_with?("refs/") + + Bundler.ui.info "Fetching #{URICredentialsFilter.credential_filtered_uri(uri)}" + + configured_uri = configured_uri_for(uri).to_s + + unless path.exist? + SharedHelpers.filesystem_access(path.dirname) do |p| + FileUtils.mkdir_p(p) + end + git_retry "clone", "--bare", "--no-hardlinks", "--quiet", "--", configured_uri, path.to_s + return unless extra_ref + end + + with_path do + git_retry(*["fetch", "--force", "--quiet", "--tags", "--", configured_uri, "refs/heads/*:refs/heads/*", extra_ref].compact, :dir => path) + end + end + + def copy_to(destination, submodules = false) + # method 1 + unless File.exist?(destination.join(".git")) + begin + SharedHelpers.filesystem_access(destination.dirname) do |p| + FileUtils.mkdir_p(p) + end + SharedHelpers.filesystem_access(destination) do |p| + FileUtils.rm_rf(p) + end + git_retry "clone", "--no-checkout", "--quiet", path.to_s, destination.to_s + File.chmod(((File.stat(destination).mode | 0o777) & ~File.umask), destination) + rescue Errno::EEXIST => e + file_path = e.message[%r{.*?((?:[a-zA-Z]:)?/.*)}, 1] + raise GitError, "Bundler could not install a gem because it needs to " \ + "create a directory, but a file exists - #{file_path}. Please delete " \ + "this file and try again." + end + end + # method 2 + git_retry "fetch", "--force", "--quiet", "--tags", path.to_s, :dir => destination + + begin + git "reset", "--hard", @revision, :dir => destination + rescue GitCommandError => e + raise MissingGitRevisionError.new(e.command, destination, @revision, URICredentialsFilter.credential_filtered_uri(uri)) + end + + if submodules + git_retry "submodule", "update", "--init", "--recursive", :dir => destination + elsif Gem::Version.create(version) >= Gem::Version.create("2.9.0") + inner_command = "git -C $toplevel submodule deinit --force $sm_path" + git_retry "submodule", "foreach", "--quiet", inner_command, :dir => destination + end + end + + private + + def git_null(*command, dir: nil) + check_allowed(command) + + out, status = SharedHelpers.with_clean_git_env do + capture_and_ignore_stderr(*capture3_args_for(command, dir)) + end + + [URICredentialsFilter.credential_filtered_string(out, uri), status] + end + + def git_retry(*command, dir: nil) + command_with_no_credentials = check_allowed(command) + + Bundler::Retry.new("`#{command_with_no_credentials}` at #{dir || SharedHelpers.pwd}").attempts do + git(*command, :dir => dir) + end + end + + def git(*command, dir: nil) + command_with_no_credentials = check_allowed(command) + + out, status = SharedHelpers.with_clean_git_env do + capture_and_filter_stderr(*capture3_args_for(command, dir)) + end + + filtered_out = URICredentialsFilter.credential_filtered_string(out, uri) + + raise GitCommandError.new(command_with_no_credentials, dir || SharedHelpers.pwd, filtered_out) unless status.success? + + filtered_out + end + + def has_revision_cached? + return unless @revision + with_path { git("cat-file", "-e", @revision, :dir => path) } + true + rescue GitError + false + end + + def remove_cache + FileUtils.rm_rf(path) + end + + def find_local_revision + allowed_with_path do + git("rev-parse", "--verify", ref || "HEAD", :dir => path).strip + end + rescue GitCommandError => e + raise MissingGitRevisionError.new(e.command, path, ref, URICredentialsFilter.credential_filtered_uri(uri)) + end + + # Adds credentials to the URI as Fetcher#configured_uri_for does + def configured_uri_for(uri) + if /https?:/ =~ uri + remote = Bundler::URI(uri) + config_auth = Bundler.settings[remote.to_s] || Bundler.settings[remote.host] + remote.userinfo ||= config_auth + remote.to_s + else + uri + end + end + + def allow? + allowed = @git ? @git.allow_git_ops? : true + + raise GitNotInstalledError.new if allowed && !Bundler.git_present? + + allowed + end + + def with_path(&blk) + checkout unless path.exist? + blk.call + end + + def allowed_with_path + return with_path { yield } if allow? + raise GitError, "The git source #{uri} is not yet checked out. Please run `bundle install` before trying to start your application" + end + + def check_allowed(command) + require "shellwords" + command_with_no_credentials = URICredentialsFilter.credential_filtered_string("git #{command.shelljoin}", uri) + raise GitNotAllowedError.new(command_with_no_credentials) unless allow? + command_with_no_credentials + end + + def capture_and_filter_stderr(*cmd) + require "open3" + return_value, captured_err, status = Open3.capture3(*cmd) + Bundler.ui.warn URICredentialsFilter.credential_filtered_string(captured_err, uri) unless captured_err.empty? + [return_value, status] + end + + def capture_and_ignore_stderr(*cmd) + require "open3" + return_value, _, status = Open3.capture3(*cmd) + [return_value, status] + end + + def capture3_args_for(cmd, dir) + return ["git", *cmd] unless dir + + if Bundler.feature_flag.bundler_3_mode? || supports_minus_c? + ["git", "-C", dir.to_s, *cmd] + else + ["git", *cmd, { :chdir => dir.to_s }] + end + end + + def supports_minus_c? + @supports_minus_c ||= Gem::Version.new(version) >= Gem::Version.new("1.8.5") + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/source/metadata.rb b/games/FNaFB2/Ruby/stdlib/bundler/source/metadata.rb new file mode 100644 index 0000000..23531b8 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/source/metadata.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module Bundler + class Source + class Metadata < Source + def specs + @specs ||= Index.build do |idx| + idx << Gem::Specification.new("Ruby\0", Gem.ruby_version) + idx << Gem::Specification.new("RubyGems\0", Gem::VERSION) do |s| + s.required_rubygems_version = Gem::Requirement.default + end + + idx << Gem::Specification.new do |s| + s.name = "bundler" + s.version = VERSION + s.license = "MIT" + s.platform = Gem::Platform::RUBY + s.source = self + s.authors = ["bundler team"] + s.bindir = "exe" + s.homepage = "https://bundler.io" + s.summary = "The best way to manage your application's dependencies" + s.executables = %w[bundle] + # can't point to the actual gemspec or else the require paths will be wrong + s.loaded_from = __dir__ + end + + if local_spec = Bundler.rubygems.find_bundler(VERSION) + idx << local_spec + end + + idx.each {|s| s.source = self } + end + end + + def options + {} + end + + def install(spec, _opts = {}) + print_using_message "Using #{version_message(spec)}" + nil + end + + def to_s + "the local ruby installation" + end + + def ==(other) + self.class == other.class + end + alias_method :eql?, :== + + def hash + self.class.hash + end + + def version_message(spec) + "#{spec.name} #{spec.version}" + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/source/path.rb b/games/FNaFB2/Ruby/stdlib/bundler/source/path.rb new file mode 100644 index 0000000..672ecfd --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/source/path.rb @@ -0,0 +1,260 @@ +# frozen_string_literal: true + +module Bundler + class Source + class Path < Source + autoload :Installer, File.expand_path("path/installer", __dir__) + + attr_reader :path, :options, :root_path, :original_path + attr_writer :name + attr_accessor :version + + protected :original_path + + DEFAULT_GLOB = "{,*,*/*}.gemspec".freeze + + def initialize(options) + @options = options.dup + @glob = options["glob"] || DEFAULT_GLOB + + @allow_cached = false + @allow_remote = false + + @root_path = options["root_path"] || root + + if options["path"] + @path = Pathname.new(options["path"]) + expanded_path = expand(@path) + @path = if @path.relative? + expanded_path.relative_path_from(root_path.expand_path) + else + expanded_path + end + end + + @name = options["name"] + @version = options["version"] + + # Stores the original path. If at any point we move to the + # cached directory, we still have the original path to copy from. + @original_path = @path + end + + def remote! + @local_specs = nil + @allow_remote = true + end + + def cached! + @local_specs = nil + @allow_cached = true + end + + def self.from_lock(options) + new(options.merge("path" => options.delete("remote"))) + end + + def to_lock + out = String.new("PATH\n") + out << " remote: #{lockfile_path}\n" + out << " glob: #{@glob}\n" unless @glob == DEFAULT_GLOB + out << " specs:\n" + end + + def to_s + "source at `#{@path}`" + end + + def hash + [self.class, expanded_path, version].hash + end + + def eql?(other) + return unless other.class == self.class + expanded_original_path == other.expanded_original_path && + version == other.version + end + + alias_method :==, :eql? + + def name + File.basename(expanded_path.to_s) + end + + def install(spec, options = {}) + using_message = "Using #{version_message(spec, options[:previous_spec])} from #{self}" + using_message += " and installing its executables" unless spec.executables.empty? + print_using_message using_message + generate_bin(spec, :disable_extensions => true) + nil # no post-install message + end + + def cache(spec, custom_path = nil) + app_cache_path = app_cache_path(custom_path) + return unless Bundler.feature_flag.cache_all? + return if expand(@original_path).to_s.index(root_path.to_s + "/") == 0 + + unless @original_path.exist? + raise GemNotFound, "Can't cache gem #{version_message(spec)} because #{self} is missing!" + end + + FileUtils.rm_rf(app_cache_path) + FileUtils.cp_r("#{@original_path}/.", app_cache_path) + FileUtils.touch(app_cache_path.join(".bundlecache")) + end + + def local_specs(*) + @local_specs ||= load_spec_files + end + + def specs + if has_app_cache? + @path = app_cache_path + @expanded_path = nil # Invalidate + end + local_specs + end + + def app_cache_dirname + name + end + + def root + Bundler.root + end + + def expanded_original_path + @expanded_original_path ||= expand(original_path) + end + + private + + def expanded_path + @expanded_path ||= expand(path) + end + + def expand(somepath) + if Bundler.current_ruby.jruby? # TODO: Unify when https://github.com/rubygems/bundler/issues/7598 fixed upstream and all supported jrubies include the fix + somepath.expand_path(root_path).expand_path + else + somepath.expand_path(root_path) + end + rescue ArgumentError => e + Bundler.ui.debug(e) + raise PathError, "There was an error while trying to use the path " \ + "`#{somepath}`.\nThe error message was: #{e.message}." + end + + def lockfile_path + return relative_path(original_path) if original_path.absolute? + expand(original_path).relative_path_from(root) + end + + def app_cache_path(custom_path = nil) + @app_cache_path ||= Bundler.app_cache(custom_path).join(app_cache_dirname) + end + + def has_app_cache? + SharedHelpers.in_bundle? && app_cache_path.exist? + end + + def load_gemspec(file) + return unless spec = Bundler.load_gemspec(file) + Bundler.rubygems.set_installed_by_version(spec) + spec + end + + def validate_spec(spec) + Bundler.rubygems.validate(spec) + end + + def load_spec_files + index = Index.new + + if File.directory?(expanded_path) + # We sort depth-first since `<<` will override the earlier-found specs + Gem::Util.glob_files_in_dir(@glob, expanded_path).sort_by {|p| -p.split(File::SEPARATOR).size }.each do |file| + next unless spec = load_gemspec(file) + spec.source = self + + # Validation causes extension_dir to be calculated, which depends + # on #source, so we validate here instead of load_gemspec + validate_spec(spec) + index << spec + end + + if index.empty? && @name && @version + index << Gem::Specification.new do |s| + s.name = @name + s.source = self + s.version = Gem::Version.new(@version) + s.platform = Gem::Platform::RUBY + s.summary = "Fake gemspec for #{@name}" + s.relative_loaded_from = "#{@name}.gemspec" + s.authors = ["no one"] + if expanded_path.join("bin").exist? + executables = expanded_path.join("bin").children + executables.reject! {|p| File.directory?(p) } + s.executables = executables.map {|c| c.basename.to_s } + end + end + end + else + message = String.new("The path `#{expanded_path}` ") + message << if File.exist?(expanded_path) + "is not a directory." + else + "does not exist." + end + raise PathError, message + end + + index + end + + def relative_path(path = self.path) + if path.to_s.start_with?(root_path.to_s) + return path.relative_path_from(root_path) + end + path + end + + def generate_bin(spec, options = {}) + gem_dir = Pathname.new(spec.full_gem_path) + + # Some gem authors put absolute paths in their gemspec + # and we have to save them from themselves + spec.files = spec.files.map do |p| + next p unless p =~ /\A#{Pathname::SEPARATOR_PAT}/ + next if File.directory?(p) + begin + Pathname.new(p).relative_path_from(gem_dir).to_s + rescue ArgumentError + p + end + end.compact + + installer = Path::Installer.new( + spec, + :env_shebang => false, + :disable_extensions => options[:disable_extensions], + :build_args => options[:build_args], + :bundler_extension_cache_path => extension_cache_path(spec) + ) + installer.post_install + rescue Gem::InvalidSpecificationException => e + Bundler.ui.warn "\n#{spec.name} at #{spec.full_gem_path} did not have a valid gemspec.\n" \ + "This prevents bundler from installing bins or native extensions, but " \ + "that may not affect its functionality." + + if !spec.extensions.empty? && !spec.email.empty? + Bundler.ui.warn "If you need to use this package without installing it from a gem " \ + "repository, please contact #{spec.email} and ask them " \ + "to modify their .gemspec so it can work with `gem build`." + end + + Bundler.ui.warn "The validation message from RubyGems was:\n #{e.message}" + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/source/path/installer.rb b/games/FNaFB2/Ruby/stdlib/bundler/source/path/installer.rb new file mode 100644 index 0000000..a70973b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/source/path/installer.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require_relative "../../rubygems_gem_installer" + +module Bundler + class Source + class Path + class Installer < Bundler::RubyGemsGemInstaller + attr_reader :spec + + def initialize(spec, options = {}) + @options = options + @spec = spec + @gem_dir = Bundler.rubygems.path(spec.full_gem_path) + @wrappers = true + @env_shebang = true + @format_executable = options[:format_executable] || false + @build_args = options[:build_args] || Bundler.rubygems.build_args + @gem_bin_dir = "#{Bundler.rubygems.gem_dir}/bin" + @disable_extensions = options[:disable_extensions] + + if Bundler.requires_sudo? + @tmp_dir = Bundler.tmp(spec.full_name).to_s + @bin_dir = "#{@tmp_dir}/bin" + else + @bin_dir = @gem_bin_dir + end + end + + def post_install + run_hooks(:pre_install) + + unless @disable_extensions + build_extensions + run_hooks(:post_build) + end + + generate_bin unless spec.executables.empty? + + run_hooks(:post_install) + ensure + Bundler.rm_rf(@tmp_dir) if Bundler.requires_sudo? + end + + private + + def generate_bin + super + + if Bundler.requires_sudo? + SharedHelpers.filesystem_access(@gem_bin_dir) do |p| + Bundler.mkdir_p(p) + end + spec.executables.each do |exe| + Bundler.sudo "cp -R #{@bin_dir}/#{exe} #{@gem_bin_dir}" + end + end + end + + def run_hooks(type) + hooks_meth = "#{type}_hooks" + return unless Gem.respond_to?(hooks_meth) + Gem.send(hooks_meth).each do |hook| + result = hook.call(self) + next unless result == false + location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/ + message = "#{type} hook#{location} failed for #{spec.full_name}" + raise InstallHookError, message + end + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/source/rubygems.rb b/games/FNaFB2/Ruby/stdlib/bundler/source/rubygems.rb new file mode 100644 index 0000000..a50934b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/source/rubygems.rb @@ -0,0 +1,567 @@ +# frozen_string_literal: true + +require "rubygems/user_interaction" + +module Bundler + class Source + class Rubygems < Source + autoload :Remote, File.expand_path("rubygems/remote", __dir__) + + # Use the API when installing less than X gems + API_REQUEST_LIMIT = 500 + # Ask for X gems per API request + API_REQUEST_SIZE = 50 + + attr_reader :remotes, :caches + + def initialize(options = {}) + @options = options + @remotes = [] + @dependency_names = [] + @allow_remote = false + @allow_cached = false + @allow_local = options["allow_local"] || false + @caches = [cache_path, *Bundler.rubygems.gem_cache] + + Array(options["remotes"]).reverse_each {|r| add_remote(r) } + end + + def local_only! + @specs = nil + @allow_local = true + @allow_cached = false + @allow_remote = false + end + + def local! + return if @allow_local + + @specs = nil + @allow_local = true + end + + def remote! + return if @allow_remote + + @specs = nil + @allow_remote = true + end + + def cached! + return if @allow_cached + + @specs = nil + @allow_local = true + @allow_cached = true + end + + def hash + @remotes.hash + end + + def eql?(other) + other.is_a?(Rubygems) && other.credless_remotes == credless_remotes + end + + alias_method :==, :eql? + + def include?(o) + o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty? + end + + def multiple_remotes? + @remotes.size > 1 + end + + def no_remotes? + @remotes.size == 0 + end + + def can_lock?(spec) + return super unless multiple_remotes? + include?(spec.source) + end + + def options + { "remotes" => @remotes.map(&:to_s) } + end + + def self.from_lock(options) + new(options) + end + + def to_lock + out = String.new("GEM\n") + remotes.reverse_each do |remote| + out << " remote: #{suppress_configured_credentials remote}\n" + end + out << " specs:\n" + end + + def to_s + if remotes.empty? + "locally installed gems" + elsif @allow_remote && @allow_cached && @allow_local + "rubygems repository #{remote_names}, cached gems or installed locally" + elsif @allow_remote && @allow_local + "rubygems repository #{remote_names} or installed locally" + elsif @allow_remote + "rubygems repository #{remote_names}" + elsif @allow_cached && @allow_local + "cached gems or installed locally" + else + "locally installed gems" + end + end + + def identifier + if remotes.empty? + "locally installed gems" + else + "rubygems repository #{remote_names}" + end + end + alias_method :name, :identifier + + def specs + @specs ||= begin + # remote_specs usually generates a way larger Index than the other + # sources, and large_idx.use small_idx is way faster than + # small_idx.use large_idx. + idx = @allow_remote ? remote_specs.dup : Index.new + idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote + idx.use(installed_specs, :override_dupes) if @allow_local + idx + end + end + + def install(spec, options = {}) + force = options[:force] + ensure_builtin_gems_cached = options[:ensure_builtin_gems_cached] + + if ensure_builtin_gems_cached && spec.default_gem? && !cached_path(spec) + cached_built_in_gem(spec) unless spec.remote + force = true + end + + if installed?(spec) && !force + print_using_message "Using #{version_message(spec)}" + return nil # no post-install message + end + + if spec.remote + # Check for this spec from other sources + uris = [spec.remote, *remotes_for_spec(spec)].map(&:anonymized_uri).uniq + Installer.ambiguous_gems << [spec.name, *uris] if uris.length > 1 + end + + path = fetch_gem_if_possible(spec, options[:previous_spec]) + raise GemNotFound, "Could not find #{spec.file_name} for installation" unless path + + return if Bundler.settings[:no_install] + + if requires_sudo? + install_path = Bundler.tmp(spec.full_name) + bin_path = install_path.join("bin") + else + install_path = rubygems_dir + bin_path = Bundler.system_bindir + end + + Bundler.mkdir_p bin_path, :no_sudo => true unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5") + + require_relative "../rubygems_gem_installer" + + installer = Bundler::RubyGemsGemInstaller.at( + path, + :security_policy => Bundler.rubygems.security_policies[Bundler.settings["trust-policy"]], + :install_dir => install_path.to_s, + :bin_dir => bin_path.to_s, + :ignore_dependencies => true, + :wrappers => true, + :env_shebang => true, + :build_args => options[:build_args], + :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum, + :bundler_extension_cache_path => extension_cache_path(spec) + ) + + if spec.remote + s = begin + installer.spec + rescue Gem::Package::FormatError + Bundler.rm_rf(path) + raise + rescue Gem::Security::Exception => e + raise SecurityError, + "The gem #{File.basename(path, ".gem")} can't be installed because " \ + "the security policy didn't allow it, with the message: #{e.message}" + end + + spec.__swap__(s) + end + + message = "Installing #{version_message(spec, options[:previous_spec])}" + message += " with native extensions" if spec.extensions.any? + Bundler.ui.confirm message + + installed_spec = installer.install + + spec.full_gem_path = installed_spec.full_gem_path + spec.loaded_from = installed_spec.loaded_from + + # SUDO HAX + if requires_sudo? + Bundler.rubygems.repository_subdirectories.each do |name| + src = File.join(install_path, name, "*") + dst = File.join(rubygems_dir, name) + if name == "extensions" && Dir.glob(src).any? + src = File.join(src, "*/*") + ext_src = Dir.glob(src).first + ext_src.gsub!(src[0..-6], "") + dst = File.dirname(File.join(dst, ext_src)) + end + SharedHelpers.filesystem_access(dst) do |p| + Bundler.mkdir_p(p) + end + Bundler.sudo "cp -R #{src} #{dst}" if Dir[src].any? + end + + spec.executables.each do |exe| + SharedHelpers.filesystem_access(Bundler.system_bindir) do |p| + Bundler.mkdir_p(p) + end + Bundler.sudo "cp -R #{install_path}/bin/#{exe} #{Bundler.system_bindir}/" + end + end + + spec.post_install_message + ensure + Bundler.rm_rf(install_path) if requires_sudo? + end + + def cache(spec, custom_path = nil) + cached_path = Bundler.settings[:cache_all_platforms] ? fetch_gem_if_possible(spec) : cached_gem(spec) + raise GemNotFound, "Missing gem file '#{spec.file_name}'." unless cached_path + return if File.dirname(cached_path) == Bundler.app_cache.to_s + Bundler.ui.info " * #{File.basename(cached_path)}" + FileUtils.cp(cached_path, Bundler.app_cache(custom_path)) + rescue Errno::EACCES => e + Bundler.ui.debug(e) + raise InstallError, e.message + end + + def cached_built_in_gem(spec) + cached_path = cached_path(spec) + if cached_path.nil? + remote_spec = remote_specs.search(spec).first + if remote_spec + cached_path = fetch_gem(remote_spec) + else + Bundler.ui.warn "#{spec.full_name} is built in to Ruby, and can't be cached because your Gemfile doesn't have any sources that contain it." + end + end + cached_path + end + + def add_remote(source) + uri = normalize_uri(source) + @remotes.unshift(uri) unless @remotes.include?(uri) + end + + def spec_names + if @allow_remote && dependency_api_available? + remote_specs.spec_names + else + [] + end + end + + def unmet_deps + if @allow_remote && dependency_api_available? + remote_specs.unmet_dependency_names + else + [] + end + end + + def fetchers + @fetchers ||= remotes.map do |uri| + remote = Source::Rubygems::Remote.new(uri) + Bundler::Fetcher.new(remote) + end + end + + def double_check_for(unmet_dependency_names) + return unless @allow_remote + return unless dependency_api_available? + + unmet_dependency_names = unmet_dependency_names.call + unless unmet_dependency_names.nil? + if api_fetchers.size <= 1 + # can't do this when there are multiple fetchers because then we might not fetch from _all_ + # of them + unmet_dependency_names -= remote_specs.spec_names # avoid re-fetching things we've already gotten + end + return if unmet_dependency_names.empty? + end + + Bundler.ui.debug "Double checking for #{unmet_dependency_names || "all specs (due to the size of the request)"} in #{self}" + + fetch_names(api_fetchers, unmet_dependency_names, specs, false) + end + + def dependency_names_to_double_check + names = [] + remote_specs.each do |spec| + case spec + when EndpointSpecification, Gem::Specification, StubSpecification, LazySpecification + names.concat(spec.runtime_dependencies.map(&:name)) + when RemoteSpecification # from the full index + return nil + else + raise "unhandled spec type (#{spec.inspect})" + end + end + names + end + + def dependency_api_available? + api_fetchers.any? + end + + protected + + def remote_names + remotes.map(&:to_s).join(", ") + end + + def credless_remotes + if Bundler.settings[:allow_deployment_source_credential_changes] + remotes.map(&method(:remove_auth)) + else + remotes.map(&method(:suppress_configured_credentials)) + end + end + + def remotes_for_spec(spec) + specs.search_all(spec.name).inject([]) do |uris, s| + uris << s.remote if s.remote + uris + end + end + + def cached_gem(spec) + if spec.default_gem? + cached_built_in_gem(spec) + else + cached_path(spec) + end + end + + def cached_path(spec) + global_cache_path = download_cache_path(spec) + @caches << global_cache_path if global_cache_path + + possibilities = @caches.map {|p| package_path(p, spec) } + possibilities.find {|p| File.exist?(p) } + end + + def package_path(cache_path, spec) + "#{cache_path}/#{spec.file_name}" + end + + def normalize_uri(uri) + uri = uri.to_s + uri = "#{uri}/" unless uri =~ %r{/$} + require_relative "../vendored_uri" + uri = Bundler::URI(uri) + raise ArgumentError, "The source must be an absolute URI. For example:\n" \ + "source 'https://rubygems.org'" if !uri.absolute? || (uri.is_a?(Bundler::URI::HTTP) && uri.host.nil?) + uri + end + + def suppress_configured_credentials(remote) + remote_nouser = remove_auth(remote) + if remote.userinfo && remote.userinfo == Bundler.settings[remote_nouser] + remote_nouser + else + remote + end + end + + def remove_auth(remote) + if remote.user || remote.password + remote.dup.tap {|uri| uri.user = uri.password = nil }.to_s + else + remote.to_s + end + end + + def installed_specs + @installed_specs ||= Index.build do |idx| + Bundler.rubygems.all_specs.reverse_each do |spec| + spec.source = self + if Bundler.rubygems.spec_missing_extensions?(spec, false) + Bundler.ui.debug "Source #{self} is ignoring #{spec} because it is missing extensions" + next + end + idx << spec + end + end + end + + def cached_specs + @cached_specs ||= begin + idx = @allow_local ? installed_specs.dup : Index.new + + Dir["#{cache_path}/*.gem"].each do |gemfile| + next if gemfile =~ /^bundler\-[\d\.]+?\.gem/ + s ||= Bundler.rubygems.spec_from_gem(gemfile) + s.source = self + idx << s + end + + idx + end + end + + def api_fetchers + fetchers.select {|f| f.use_api && f.fetchers.first.api_fetcher? } + end + + def remote_specs + @remote_specs ||= Index.build do |idx| + index_fetchers = fetchers - api_fetchers + + # gather lists from non-api sites + fetch_names(index_fetchers, nil, idx, false) + + # because ensuring we have all the gems we need involves downloading + # the gemspecs of those gems, if the non-api sites contain more than + # about 500 gems, we treat all sites as non-api for speed. + allow_api = idx.size < API_REQUEST_LIMIT && dependency_names.size < API_REQUEST_LIMIT + Bundler.ui.debug "Need to query more than #{API_REQUEST_LIMIT} gems." \ + " Downloading full index instead..." unless allow_api + + fetch_names(api_fetchers, allow_api && dependency_names, idx, false) + end + end + + def fetch_names(fetchers, dependency_names, index, override_dupes) + fetchers.each do |f| + if dependency_names + Bundler.ui.info "Fetching gem metadata from #{URICredentialsFilter.credential_filtered_uri(f.uri)}", Bundler.ui.debug? + index.use f.specs_with_retry(dependency_names, self), override_dupes + Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over + else + Bundler.ui.info "Fetching source index from #{URICredentialsFilter.credential_filtered_uri(f.uri)}" + index.use f.specs_with_retry(nil, self), override_dupes + end + end + end + + def fetch_gem_if_possible(spec, previous_spec = nil) + if spec.remote + fetch_gem(spec, previous_spec) + else + cached_gem(spec) + end + end + + def fetch_gem(spec, previous_spec = nil) + spec.fetch_platform + + cache_path = download_cache_path(spec) || default_cache_path_for(rubygems_dir) + gem_path = package_path(cache_path, spec) + return gem_path if File.exist?(gem_path) + + if requires_sudo? + download_path = Bundler.tmp(spec.full_name) + download_cache_path = default_cache_path_for(download_path) + else + download_cache_path = cache_path + end + + SharedHelpers.filesystem_access(download_cache_path) do |p| + FileUtils.mkdir_p(p) + end + download_gem(spec, download_cache_path, previous_spec) + + if requires_sudo? + SharedHelpers.filesystem_access(cache_path) do |p| + Bundler.mkdir_p(p) + end + Bundler.sudo "mv #{package_path(download_cache_path, spec)} #{gem_path}" + end + + gem_path + ensure + Bundler.rm_rf(download_path) if requires_sudo? + end + + def installed?(spec) + installed_specs[spec].any? && !spec.deleted_gem? + end + + def requires_sudo? + Bundler.requires_sudo? + end + + def rubygems_dir + Bundler.bundle_path + end + + def default_cache_path_for(dir) + "#{dir}/cache" + end + + def cache_path + Bundler.app_cache + end + + private + + # Checks if the requested spec exists in the global cache. If it does, + # we copy it to the download path, and if it does not, we download it. + # + # @param [Specification] spec + # the spec we want to download or retrieve from the cache. + # + # @param [String] download_cache_path + # the local directory the .gem will end up in. + # + # @param [Specification] previous_spec + # the spec previously locked + # + def download_gem(spec, download_cache_path, previous_spec = nil) + uri = spec.remote.uri + Bundler.ui.confirm("Fetching #{version_message(spec, previous_spec)}") + Bundler.rubygems.download_gem(spec, uri, download_cache_path) + end + + # Returns the global cache path of the calling Rubygems::Source object. + # + # Note that the Source determines the path's subdirectory. We use this + # subdirectory in the global cache path so that gems with the same name + # -- and possibly different versions -- from different sources are saved + # to their respective subdirectories and do not override one another. + # + # @param [Gem::Specification] specification + # + # @return [Pathname] The global cache path. + # + def download_cache_path(spec) + return unless Bundler.feature_flag.global_gem_cache? + return unless remote = spec.remote + return unless cache_slug = remote.cache_slug + + Bundler.user_cache.join("gems", cache_slug) + end + + def extension_cache_slug(spec) + return unless remote = spec.remote + remote.cache_slug + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/source/rubygems/remote.rb b/games/FNaFB2/Ruby/stdlib/bundler/source/rubygems/remote.rb new file mode 100644 index 0000000..82c850f --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/source/rubygems/remote.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +module Bundler + class Source + class Rubygems + class Remote + attr_reader :uri, :anonymized_uri, :original_uri + + def initialize(uri) + orig_uri = uri + uri = Bundler.settings.mirror_for(uri) + @original_uri = orig_uri if orig_uri != uri + fallback_auth = Bundler.settings.credentials_for(uri) + + @uri = apply_auth(uri, fallback_auth).freeze + @anonymized_uri = remove_auth(@uri).freeze + end + + # @return [String] A slug suitable for use as a cache key for this + # remote. + # + def cache_slug + @cache_slug ||= begin + return nil unless SharedHelpers.md5_available? + + cache_uri = original_uri || uri + + host = cache_uri.to_s.start_with?("file://") ? nil : cache_uri.host + + uri_parts = [host, cache_uri.user, cache_uri.port, cache_uri.path] + uri_digest = SharedHelpers.digest(:MD5).hexdigest(uri_parts.compact.join(".")) + + uri_parts[-1] = uri_digest + uri_parts.compact.join(".") + end + end + + def to_s + "rubygems remote at #{anonymized_uri}" + end + + private + + def apply_auth(uri, auth) + if auth && uri.userinfo.nil? + uri = uri.dup + uri.userinfo = auth + end + + uri + rescue Bundler::URI::InvalidComponentError + error_message = "Please CGI escape your usernames and passwords before " \ + "setting them for authentication." + raise HTTPError.new(error_message) + end + + def remove_auth(uri) + if uri.userinfo + uri = uri.dup + uri.user = uri.password = nil + end + + uri + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/source/rubygems_aggregate.rb b/games/FNaFB2/Ruby/stdlib/bundler/source/rubygems_aggregate.rb new file mode 100644 index 0000000..99ef81a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/source/rubygems_aggregate.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +module Bundler + class Source + class RubygemsAggregate + attr_reader :source_map, :sources + + def initialize(sources, source_map) + @sources = sources + @source_map = source_map + + @index = build_index + end + + def specs + @index + end + + def identifier + to_s + end + + def to_s + "any of the sources" + end + + private + + def build_index + Index.build do |idx| + dependency_names = source_map.pinned_spec_names + + sources.all_sources.each do |source| + source.dependency_names = dependency_names - source_map.pinned_spec_names(source) + idx.add_source source.specs + dependency_names.concat(source.unmet_deps).uniq! + end + + double_check_for_index(idx, dependency_names) + end + end + + # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both + # sources A and B. At this point, the API request will have found all the versions of Bar in source A, + # but will not have found any versions of Bar from source B, which is a problem if the requested version + # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for + # each spec we found, we add all possible versions from all sources to the index. + def double_check_for_index(idx, dependency_names) + pinned_names = source_map.pinned_spec_names + + names = :names # do this so we only have to traverse to get dependency_names from the index once + unmet_dependency_names = lambda do + return names unless names == :names + new_names = sources.all_sources.map(&:dependency_names_to_double_check) + return names = nil if new_names.compact! + names = new_names.flatten(1).concat(dependency_names) + names.uniq! + names -= pinned_names + names + end + + sources.all_sources.each do |source| + source.double_check_for(unmet_dependency_names) + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/source_list.rb b/games/FNaFB2/Ruby/stdlib/bundler/source_list.rb new file mode 100644 index 0000000..6ea2910 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/source_list.rb @@ -0,0 +1,225 @@ +# frozen_string_literal: true + +module Bundler + class SourceList + attr_reader :path_sources, + :git_sources, + :plugin_sources, + :global_path_source, + :metadata_source + + def global_rubygems_source + @global_rubygems_source ||= rubygems_aggregate_class.new("allow_local" => true) + end + + def initialize + @path_sources = [] + @git_sources = [] + @plugin_sources = [] + @global_rubygems_source = nil + @global_path_source = nil + @rubygems_sources = [] + @metadata_source = Source::Metadata.new + + @merged_gem_lockfile_sections = false + end + + def merged_gem_lockfile_sections? + @merged_gem_lockfile_sections + end + + def merged_gem_lockfile_sections!(replacement_source) + @merged_gem_lockfile_sections = true + @global_rubygems_source = replacement_source + end + + def aggregate_global_source? + global_rubygems_source.multiple_remotes? + end + + def implicit_global_source? + global_rubygems_source.no_remotes? + end + + def add_path_source(options = {}) + if options["gemspec"] + add_source_to_list Source::Gemspec.new(options), path_sources + else + path_source = add_source_to_list Source::Path.new(options), path_sources + @global_path_source ||= path_source if options["global"] + path_source + end + end + + def add_git_source(options = {}) + add_source_to_list(Source::Git.new(options), git_sources).tap do |source| + warn_on_git_protocol(source) + end + end + + def add_rubygems_source(options = {}) + new_source = Source::Rubygems.new(options) + return @global_rubygems_source if @global_rubygems_source == new_source + + add_source_to_list new_source, @rubygems_sources + end + + def add_plugin_source(source, options = {}) + add_source_to_list Plugin.source(source).new(options), @plugin_sources + end + + def add_global_rubygems_remote(uri) + global_rubygems_source.add_remote(uri) + global_rubygems_source + end + + def default_source + global_path_source || global_rubygems_source + end + + def rubygems_sources + non_global_rubygems_sources + [global_rubygems_source] + end + + def non_global_rubygems_sources + @rubygems_sources + end + + def rubygems_remotes + rubygems_sources.map(&:remotes).flatten.uniq + end + + def all_sources + path_sources + git_sources + plugin_sources + rubygems_sources + [metadata_source] + end + + def non_default_explicit_sources + all_sources - [default_source, metadata_source] + end + + def get(source) + source_list_for(source).find {|s| equivalent_source?(source, s) } + end + + def get_with_fallback(source) + get(source) || default_source + end + + def lock_sources + lock_other_sources + lock_rubygems_sources + end + + def lock_other_sources + (path_sources + git_sources + plugin_sources).sort_by(&:identifier) + end + + def lock_rubygems_sources + if merged_gem_lockfile_sections? + [combine_rubygems_sources] + else + rubygems_sources.sort_by(&:identifier) + end + end + + # Returns true if there are changes + def replace_sources!(replacement_sources) + return false if replacement_sources.empty? + + @rubygems_sources, @path_sources, @git_sources, @plugin_sources = map_sources(replacement_sources) + @global_rubygems_source = global_replacement_source(replacement_sources) + + different_sources?(lock_sources, replacement_sources) + end + + # Returns true if there are changes + def expired_sources?(replacement_sources) + return false if replacement_sources.empty? + + lock_sources = dup_with_replaced_sources(replacement_sources).lock_sources + + different_sources?(lock_sources, replacement_sources) + end + + def local_only! + all_sources.each(&:local_only!) + end + + def cached! + all_sources.each(&:cached!) + end + + def remote! + all_sources.each(&:remote!) + end + + private + + def dup_with_replaced_sources(replacement_sources) + new_source_list = dup + new_source_list.replace_sources!(replacement_sources) + new_source_list + end + + def map_sources(replacement_sources) + [@rubygems_sources, @path_sources, @git_sources, @plugin_sources].map do |sources| + sources.map do |source| + replacement_sources.find {|s| s == source } || source + end + end + end + + def global_replacement_source(replacement_sources) + replacement_source = replacement_sources.find {|s| s == global_rubygems_source } + return global_rubygems_source unless replacement_source + + replacement_source.local! + replacement_source + end + + def different_sources?(lock_sources, replacement_sources) + !equivalent_sources?(lock_sources, replacement_sources) + end + + def rubygems_aggregate_class + Source::Rubygems + end + + def add_source_to_list(source, list) + list.unshift(source).uniq! + source + end + + def source_list_for(source) + case source + when Source::Git then git_sources + when Source::Path then path_sources + when Source::Rubygems then rubygems_sources + when Plugin::API::Source then plugin_sources + else raise ArgumentError, "Invalid source: #{source.inspect}" + end + end + + def combine_rubygems_sources + Source::Rubygems.new("remotes" => rubygems_remotes) + end + + def warn_on_git_protocol(source) + return if Bundler.settings["git.allow_insecure"] + + if source.uri =~ /^git\:/ + Bundler.ui.warn "The git source `#{source.uri}` uses the `git` protocol, " \ + "which transmits data without encryption. Disable this warning with " \ + "`bundle config set --local git.allow_insecure true`, or switch to the `https` " \ + "protocol to keep your data secure." + end + end + + def equivalent_sources?(lock_sources, replacement_sources) + lock_sources.sort_by(&:identifier) == replacement_sources.sort_by(&:identifier) + end + + def equivalent_source?(source, other_source) + source == other_source + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/source_map.rb b/games/FNaFB2/Ruby/stdlib/bundler/source_map.rb new file mode 100644 index 0000000..ca73e01 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/source_map.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +module Bundler + class SourceMap + attr_reader :sources, :dependencies, :locked_specs + + def initialize(sources, dependencies, locked_specs) + @sources = sources + @dependencies = dependencies + @locked_specs = locked_specs + end + + def pinned_spec_names(skip = nil) + direct_requirements.reject {|_, source| source == skip }.keys + end + + def all_requirements + requirements = direct_requirements.dup + + unmet_deps = sources.non_default_explicit_sources.map do |source| + (source.spec_names - pinned_spec_names).each do |indirect_dependency_name| + previous_source = requirements[indirect_dependency_name] + if previous_source.nil? + requirements[indirect_dependency_name] = source + else + no_ambiguous_sources = Bundler.feature_flag.bundler_3_mode? + + msg = ["The gem '#{indirect_dependency_name}' was found in multiple relevant sources."] + msg.concat [previous_source, source].map {|s| " * #{s}" }.sort + msg << "You #{no_ambiguous_sources ? :must : :should} add this gem to the source block for the source you wish it to be installed from." + msg = msg.join("\n") + + raise SecurityError, msg if no_ambiguous_sources + Bundler.ui.warn "Warning: #{msg}" + end + end + + source.unmet_deps + end + + sources.default_source.add_dependency_names(unmet_deps.flatten - requirements.keys) + + requirements + end + + def direct_requirements + @direct_requirements ||= begin + requirements = {} + default = sources.default_source + dependencies.each do |dep| + dep_source = dep.source || default + dep_source.add_dependency_names(dep.name) + requirements[dep.name] = dep_source + end + requirements + end + end + + def locked_requirements + @locked_requirements ||= begin + requirements = {} + locked_specs.each do |locked_spec| + source = locked_spec.source + source.add_dependency_names(locked_spec.name) + requirements[locked_spec.name] = source + end + requirements + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/spec_set.rb b/games/FNaFB2/Ruby/stdlib/bundler/spec_set.rb new file mode 100644 index 0000000..21d57fd --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/spec_set.rb @@ -0,0 +1,208 @@ +# frozen_string_literal: true + +require_relative "vendored_tsort" + +module Bundler + class SpecSet + include Enumerable + include TSort + + attr_reader :incomplete_specs + + def initialize(specs, incomplete_specs = []) + @specs = specs + @incomplete_specs = incomplete_specs + end + + def for(dependencies, check = false, platforms = [nil]) + handled = ["bundler"].product(platforms).map {|k| [k, true] }.to_h + deps = dependencies.product(platforms) + specs = [] + + loop do + break unless dep = deps.shift + + name = dep[0].name + platform = dep[1] + + key = [name, platform] + next if handled.key?(key) + + handled[key] = true + + specs_for_dep = specs_for_dependency(*dep) + if specs_for_dep.any? + specs.concat(specs_for_dep) + + specs_for_dep.first.dependencies.each do |d| + next if d.type == :development + deps << [d, dep[1]] + end + elsif check + @incomplete_specs += lookup[name] + end + end + + specs + end + + def [](key) + key = key.name if key.respond_to?(:name) + lookup[key].reverse + end + + def []=(key, value) + @specs << value + @lookup = nil + @sorted = nil + end + + def delete(spec) + @specs.delete(spec) + @lookup = nil + @sorted = nil + end + + def sort! + self + end + + def to_a + sorted.dup + end + + def to_hash + lookup.dup + end + + def materialize(deps) + materialized = self.for(deps, true) + + SpecSet.new(materialized, incomplete_specs) + end + + # Materialize for all the specs in the spec set, regardless of what platform they're for + # This is in contrast to how for does platform filtering (and specifically different from how `materialize` calls `for` only for the current platform) + # @return [Array] + def materialized_for_all_platforms + @specs.map do |s| + next s unless s.is_a?(LazySpecification) + s.source.remote! + spec = s.materialize_for_installation + raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec + spec + end + end + + def incomplete_ruby_specs?(deps) + self.for(deps, true, [Gem::Platform::RUBY]) + + @incomplete_specs.any? + end + + def missing_specs + @specs.select {|s| s.is_a?(LazySpecification) } + end + + def merge(set) + arr = sorted.dup + set.each do |set_spec| + full_name = set_spec.full_name + next if arr.any? {|spec| spec.full_name == full_name } + arr << set_spec + end + SpecSet.new(arr) + end + + def -(other) + SpecSet.new(to_a - other.to_a) + end + + def find_by_name_and_platform(name, platform) + @specs.detect {|spec| spec.name == name && spec.match_platform(platform) } + end + + def delete_by_name_and_version(name, version) + @specs.reject! {|spec| spec.name == name && spec.version == version } + @lookup = nil + @sorted = nil + end + + def what_required(spec) + unless req = find {|s| s.dependencies.any? {|d| d.type == :runtime && d.name == spec.name } } + return [spec] + end + what_required(req) << spec + end + + def <<(spec) + @specs << spec + end + + def length + @specs.length + end + + def size + @specs.size + end + + def empty? + @specs.empty? + end + + def each(&b) + sorted.each(&b) + end + + private + + def sorted + rake = @specs.find {|s| s.name == "rake" } + begin + @sorted ||= ([rake] + tsort).compact.uniq + rescue TSort::Cyclic => error + cgems = extract_circular_gems(error) + raise CyclicDependencyError, "Your bundle requires gems that depend" \ + " on each other, creating an infinite loop. Please remove either" \ + " gem '#{cgems[1]}' or gem '#{cgems[0]}' and try again." + end + end + + def extract_circular_gems(error) + error.message.scan(/@name="(.*?)"/).flatten + end + + def lookup + @lookup ||= begin + lookup = Hash.new {|h, k| h[k] = [] } + @specs.each do |s| + lookup[s.name] << s + end + lookup + end + end + + def tsort_each_node + # MUST sort by name for backwards compatibility + @specs.sort_by(&:name).each {|s| yield s } + end + + def specs_for_dependency(dep, platform) + specs_for_name = lookup[dep.name] + if platform.nil? + matching_specs = specs_for_name.map {|s| s.materialize_for_installation if Gem::Platform.match_spec?(s) }.compact + GemHelpers.sort_best_platform_match(matching_specs, Bundler.local_platform) + else + GemHelpers.select_best_platform_match(specs_for_name, dep.force_ruby_platform ? Gem::Platform::RUBY : platform) + end + end + + def tsort_each_child(s) + s.dependencies.sort_by(&:name).each do |d| + next if d.type == :development + lookup[d.name].each {|s2| yield s2 } + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/stub_specification.rb b/games/FNaFB2/Ruby/stdlib/bundler/stub_specification.rb new file mode 100644 index 0000000..88a4257 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/stub_specification.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true + +module Bundler + class StubSpecification < RemoteSpecification + def self.from_stub(stub) + return stub if stub.is_a?(Bundler::StubSpecification) + spec = new(stub.name, stub.version, stub.platform, nil) + spec.stub = stub + spec + end + + attr_accessor :stub, :ignored + + def source=(source) + super + # Stub has no concept of source, which means that extension_dir may be wrong + # This is the case for git-based gems. So, instead manually assign the extension dir + return unless source.respond_to?(:extension_dir_name) + path = File.join(stub.extensions_dir, source.extension_dir_name) + stub.extension_dir = File.expand_path(path) + end + + def to_yaml + _remote_specification.to_yaml + end + + # @!group Stub Delegates + + def manually_installed? + # This is for manually installed gems which are gems that were fixed in place after a + # failed installation. Once the issue was resolved, the user then manually created + # the gem specification using the instructions provided by `gem help install` + installed_by_version == Gem::Version.new(0) + end + + # This is defined directly to avoid having to loading the full spec + def missing_extensions? + return false if default_gem? + return false if extensions.empty? + return false if File.exist? gem_build_complete_path + return false if manually_installed? + + true + end + + def activated + stub.activated + end + + def activated=(activated) + stub.instance_variable_set(:@activated, activated) + end + + def extensions + stub.extensions + end + + def gem_build_complete_path + File.join(extension_dir, "gem.build_complete") + end + + def default_gem? + stub.default_gem? + end + + def full_gem_path + stub.full_gem_path + end + + def full_gem_path=(path) + stub.full_gem_path = path + end + + def full_require_paths + stub.full_require_paths + end + + def load_paths + full_require_paths + end + + def loaded_from + stub.loaded_from + end + + def matches_for_glob(glob) + stub.matches_for_glob(glob) + end + + def raw_require_paths + stub.raw_require_paths + end + + private + + def _remote_specification + @_remote_specification ||= begin + rs = stub.to_spec + if rs.equal?(self) # happens when to_spec gets the spec from Gem.loaded_specs + rs = Gem::Specification.load(loaded_from) + Bundler.rubygems.stub_set_spec(stub, rs) + end + + unless rs + raise GemspecError, "The gemspec for #{full_name} at #{loaded_from}" \ + " was missing or broken. Try running `gem pristine #{name} -v #{version}`" \ + " to fix the cached spec." + end + + rs.source = source + + rs + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/Executable b/games/FNaFB2/Ruby/stdlib/bundler/templates/Executable new file mode 100644 index 0000000..f6487e3 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/Executable @@ -0,0 +1,27 @@ +#!/usr/bin/env <%= Bundler.settings[:shebang] || RbConfig::CONFIG["ruby_install_name"] %> +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application '<%= executable %>' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("<%= relative_gemfile_path %>", __dir__) + +bundle_binstub = File.expand_path("bundle", __dir__) + +if File.file?(bundle_binstub) + if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ + load(bundle_binstub) + else + abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. +Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") + end +end + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("<%= spec.name %>", "<%= executable %>") diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/Executable.bundler b/games/FNaFB2/Ruby/stdlib/bundler/templates/Executable.bundler new file mode 100644 index 0000000..51650c7 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/Executable.bundler @@ -0,0 +1,114 @@ +#!/usr/bin/env <%= Bundler.settings[:shebang] || RbConfig::CONFIG["ruby_install_name"] %> +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application '<%= executable %>' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "rubygems" + +m = Module.new do + module_function + + def invoked_as_script? + File.expand_path($0) == File.expand_path(__FILE__) + end + + def env_var_version + ENV["BUNDLER_VERSION"] + end + + def cli_arg_version + return unless invoked_as_script? # don't want to hijack other binstubs + return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` + bundler_version = nil + update_index = nil + ARGV.each_with_index do |a, i| + if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN + bundler_version = a + end + next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/ + bundler_version = $1 + update_index = i + end + bundler_version + end + + def gemfile + gemfile = ENV["BUNDLE_GEMFILE"] + return gemfile if gemfile && !gemfile.empty? + + File.expand_path("<%= relative_gemfile_path %>", __dir__) + end + + def lockfile + lockfile = + case File.basename(gemfile) + when "gems.rb" then gemfile.sub(/\.rb$/, gemfile) + else "#{gemfile}.lock" + end + File.expand_path(lockfile) + end + + def lockfile_version + return unless File.file?(lockfile) + lockfile_contents = File.read(lockfile) + return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/ + Regexp.last_match(1) + end + + def bundler_requirement + @bundler_requirement ||= + env_var_version || cli_arg_version || + bundler_requirement_for(lockfile_version) + end + + def bundler_requirement_for(version) + return "#{Gem::Requirement.default}.a" unless version + + bundler_gem_version = Gem::Version.new(version) + + requirement = bundler_gem_version.approximate_recommendation + + return requirement unless Gem.rubygems_version < Gem::Version.new("2.7.0") + + requirement += ".a" if bundler_gem_version.prerelease? + + requirement + end + + def load_bundler! + ENV["BUNDLE_GEMFILE"] ||= gemfile + + activate_bundler + end + + def activate_bundler + gem_error = activation_error_handling do + gem "bundler", bundler_requirement + end + return if gem_error.nil? + require_error = activation_error_handling do + require "bundler/version" + end + return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION)) + warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`" + exit 42 + end + + def activation_error_handling + yield + nil + rescue StandardError, LoadError => e + e + end +end + +m.load_bundler! + +if m.invoked_as_script? + load Gem.bin_path("<%= spec.name %>", "<%= executable %>") +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/Executable.standalone b/games/FNaFB2/Ruby/stdlib/bundler/templates/Executable.standalone new file mode 100644 index 0000000..d591e3f --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/Executable.standalone @@ -0,0 +1,12 @@ +#!/usr/bin/env <%= Bundler.settings[:shebang] || RbConfig::CONFIG["ruby_install_name"] %> +# +# This file was generated by Bundler. +# +# The application '<%= executable %>' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +$:.unshift File.expand_path "<%= standalone_path %>", __dir__ + +require "bundler/setup" +load File.expand_path "<%= executable_path %>", __dir__ diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/Gemfile b/games/FNaFB2/Ruby/stdlib/bundler/templates/Gemfile new file mode 100644 index 0000000..d2403f1 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +# gem "rails" diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/gems.rb b/games/FNaFB2/Ruby/stdlib/bundler/templates/gems.rb new file mode 100644 index 0000000..d2403f1 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/gems.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +# gem "rails" diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/CHANGELOG.md.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/CHANGELOG.md.tt new file mode 100644 index 0000000..c9ea96d --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/CHANGELOG.md.tt @@ -0,0 +1,5 @@ +## [Unreleased] + +## [0.1.0] - <%= Time.now.strftime('%F') %> + +- Initial release diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt new file mode 100644 index 0000000..175b821 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt @@ -0,0 +1,84 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at <%= config[:email] %>. All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of actions. + +**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, +available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/Gemfile.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/Gemfile.tt new file mode 100644 index 0000000..de82a63 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/Gemfile.tt @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +# Specify your gem's dependencies in <%= config[:name] %>.gemspec +gemspec + +gem "rake", "~> 13.0" +<%- if config[:ext] -%> + +gem "rake-compiler" +<%- end -%> +<%- if config[:test] -%> + +gem "<%= config[:test] %>", "~> <%= config[:test_framework_version] %>" +<%- end -%> +<%- if config[:linter] == "rubocop" -%> + +gem "rubocop", "~> <%= config[:linter_version] %>" +<%- elsif config[:linter] == "standard" -%> + +gem "standard", "~> <%= config[:linter_version] %>" +<%- end -%> diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/LICENSE.txt.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/LICENSE.txt.tt new file mode 100644 index 0000000..76ef4b0 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/LICENSE.txt.tt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) <%= Time.now.year %> <%= config[:author] %> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/README.md.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/README.md.tt new file mode 100644 index 0000000..a60c796 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/README.md.tt @@ -0,0 +1,43 @@ +# <%= config[:constant_name] %> + +Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/<%= config[:namespaced_path] %>`. To experiment with that code, run `bin/console` for an interactive prompt. + +TODO: Delete this and the text above, and describe your gem + +## Installation + +Install the gem and add to the application's Gemfile by executing: + + $ bundle add <%= config[:name] %> + +If bundler is not being used to manage dependencies, install the gem by executing: + + $ gem install <%= config[:name] %> + +## Usage + +TODO: Write usage instructions here + +## Development + +After checking out the repo, run `bin/setup` to install dependencies.<% if config[:test] %> Then, run `rake <%= config[:test].sub('mini', '').sub('rspec', 'spec') %>` to run the tests.<% end %> You can also run `bin/console` for an interactive prompt that will allow you to experiment.<% if config[:bin] %> Run `bundle exec <%= config[:name] %>` to use the gem in this directory, ignoring other installed copies of this gem.<% end %> + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org). +<% if config[:git] -%> + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/<%= config[:github_username] %>/<%= config[:name] %>.<% if config[:coc] %> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/<%= config[:git_default_branch] %>/CODE_OF_CONDUCT.md).<% end %> +<% end -%> +<% if config[:mit] -%> + +## License + +The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). +<% end -%> +<% if config[:git] && config[:coc] -%> + +## Code of Conduct + +Everyone interacting in the <%= config[:constant_name] %> project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/<%= config[:git_default_branch] %>/CODE_OF_CONDUCT.md). +<% end -%> diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/Rakefile.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/Rakefile.tt new file mode 100644 index 0000000..b02ada9 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/Rakefile.tt @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require "bundler/gem_tasks" +<% default_task_names = [config[:test_task]].compact -%> +<% case config[:test] -%> +<% when "minitest" -%> +require "rake/testtask" + +Rake::TestTask.new(:test) do |t| + t.libs << "test" + t.libs << "lib" + t.test_files = FileList["test/**/test_*.rb"] +end + +<% when "test-unit" -%> +require "rake/testtask" + +Rake::TestTask.new(:test) do |t| + t.libs << "test" + t.libs << "lib" + t.test_files = FileList["test/**/*_test.rb"] +end + +<% when "rspec" -%> +require "rspec/core/rake_task" + +RSpec::Core::RakeTask.new(:spec) + +<% end -%> +<% if config[:linter] == "rubocop" -%> +<% default_task_names << :rubocop -%> +require "rubocop/rake_task" + +RuboCop::RakeTask.new + +<% elsif config[:linter] == "standard" -%> +<% default_task_names << :standard -%> +require "standard/rake" + +<% end -%> +<% if config[:ext] -%> +<% default_task_names.unshift(:clobber, :compile) -%> +require "rake/extensiontask" + +task build: :compile + +Rake::ExtensionTask.new("<%= config[:underscored_name] %>") do |ext| + ext.lib_dir = "lib/<%= config[:namespaced_path] %>" +end + +<% end -%> +<% if default_task_names.size == 1 -%> +task default: <%= default_task_names.first.inspect %> +<% else -%> +task default: %i[<%= default_task_names.join(" ") %>] +<% end -%> diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/bin/console.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/bin/console.tt new file mode 100644 index 0000000..08dfaae --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/bin/console.tt @@ -0,0 +1,15 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require "bundler/setup" +require "<%= config[:namespaced_path] %>" + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +# (If you use this, don't forget to add pry to your Gemfile!) +# require "pry" +# Pry.start + +require "irb" +IRB.start(__FILE__) diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/bin/setup.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/bin/setup.tt new file mode 100644 index 0000000..dce67d8 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/bin/setup.tt @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' +set -vx + +bundle install + +# Do any other automated setup that you need to do here diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/circleci/config.yml.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/circleci/config.yml.tt new file mode 100644 index 0000000..79fd0dc --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/circleci/config.yml.tt @@ -0,0 +1,13 @@ +version: 2.1 +jobs: + build: + docker: + - image: ruby:<%= RUBY_VERSION %> + steps: + - checkout + - run: + name: Run the default task + command: | + gem install bundler -v <%= Bundler::VERSION %> + bundle install + bundle exec rake diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/exe/newgem.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/exe/newgem.tt new file mode 100644 index 0000000..a8339bb --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/exe/newgem.tt @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby + +require "<%= config[:namespaced_path] %>" diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/ext/newgem/extconf.rb.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/ext/newgem/extconf.rb.tt new file mode 100644 index 0000000..e918063 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/ext/newgem/extconf.rb.tt @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +require "mkmf" + +create_makefile(<%= config[:makefile_path].inspect %>) diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/ext/newgem/newgem.c.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/ext/newgem/newgem.c.tt new file mode 100644 index 0000000..8177c4d --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/ext/newgem/newgem.c.tt @@ -0,0 +1,9 @@ +#include "<%= config[:underscored_name] %>.h" + +VALUE rb_m<%= config[:constant_array].join %>; + +void +Init_<%= config[:underscored_name] %>(void) +{ + rb_m<%= config[:constant_array].join %> = rb_define_module(<%= config[:constant_name].inspect %>); +} diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/ext/newgem/newgem.h.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/ext/newgem/newgem.h.tt new file mode 100644 index 0000000..c6e420b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/ext/newgem/newgem.h.tt @@ -0,0 +1,6 @@ +#ifndef <%= config[:underscored_name].upcase %>_H +#define <%= config[:underscored_name].upcase %>_H 1 + +#include "ruby.h" + +#endif /* <%= config[:underscored_name].upcase %>_H */ diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/github/workflows/main.yml.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/github/workflows/main.yml.tt new file mode 100644 index 0000000..1ff4b58 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/github/workflows/main.yml.tt @@ -0,0 +1,27 @@ +name: Ruby + +on: + push: + branches: + - <%= config[:git_default_branch] %> + + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + name: Ruby ${{ matrix.ruby }} + strategy: + matrix: + ruby: + - '<%= RUBY_VERSION %>' + + steps: + - uses: actions/checkout@v3 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + - name: Run the default task + run: bundle exec rake diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/gitignore.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/gitignore.tt new file mode 100644 index 0000000..b1c9f99 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/gitignore.tt @@ -0,0 +1,20 @@ +/.bundle/ +/.yardoc +/_yardoc/ +/coverage/ +/doc/ +/pkg/ +/spec/reports/ +/tmp/ +<%- if config[:ext] -%> +*.bundle +*.so +*.o +*.a +mkmf.log +<%- end -%> +<%- if config[:test] == "rspec" -%> + +# rspec failure tracking +.rspec_status +<%- end -%> diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/gitlab-ci.yml.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/gitlab-ci.yml.tt new file mode 100644 index 0000000..42e0039 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/gitlab-ci.yml.tt @@ -0,0 +1,10 @@ +default: + image: ruby:<%= RUBY_VERSION %> + + before_script: + - gem install bundler -v <%= Bundler::VERSION %> + - bundle install + +example_job: + script: + - bundle exec rake diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/lib/newgem.rb.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/lib/newgem.rb.tt new file mode 100644 index 0000000..caf6e32 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/lib/newgem.rb.tt @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require_relative "<%= File.basename(config[:namespaced_path]) %>/version" +<%- if config[:ext] -%> +require_relative "<%= File.basename(config[:namespaced_path]) %>/<%= config[:underscored_name] %>" +<%- end -%> + +<%- config[:constant_array].each_with_index do |c, i| -%> +<%= " " * i %>module <%= c %> +<%- end -%> +<%= " " * config[:constant_array].size %>class Error < StandardError; end +<%= " " * config[:constant_array].size %># Your code goes here... +<%- (config[:constant_array].size-1).downto(0) do |i| -%> +<%= " " * i %>end +<%- end -%> diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/lib/newgem/version.rb.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/lib/newgem/version.rb.tt new file mode 100644 index 0000000..b5cd4cb --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/lib/newgem/version.rb.tt @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +<%- config[:constant_array].each_with_index do |c, i| -%> +<%= " " * i %>module <%= c %> +<%- end -%> +<%= " " * config[:constant_array].size %>VERSION = "0.1.0" +<%- (config[:constant_array].size-1).downto(0) do |i| -%> +<%= " " * i %>end +<%- end -%> diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/newgem.gemspec.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/newgem.gemspec.tt new file mode 100644 index 0000000..ceb2e9b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/newgem.gemspec.tt @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require_relative "lib/<%=config[:namespaced_path]%>/version" + +Gem::Specification.new do |spec| + spec.name = <%= config[:name].inspect %> + spec.version = <%= config[:constant_name] %>::VERSION + spec.authors = [<%= config[:author].inspect %>] + spec.email = [<%= config[:email].inspect %>] + + spec.summary = "TODO: Write a short summary, because RubyGems requires one." + spec.description = "TODO: Write a longer description or delete this line." + spec.homepage = "TODO: Put your gem's website or public repo URL here." +<%- if config[:mit] -%> + spec.license = "MIT" +<%- end -%> + spec.required_ruby_version = ">= <%= config[:required_ruby_version] %>" + + spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'" + + spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here." + spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here." + + # Specify which files should be added to the gem when it is released. + # The `git ls-files -z` loads the files in the RubyGem that have been added into git. + spec.files = Dir.chdir(__dir__) do + `git ls-files -z`.split("\x0").reject do |f| + (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)}) + end + end + spec.bindir = "exe" + spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } + spec.require_paths = ["lib"] +<%- if config[:ext] -%> + spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"] +<%- end -%> + + # Uncomment to register a new dependency of your gem + # spec.add_dependency "example-gem", "~> 1.0" + + # For more information and examples about making a new gem, check out our + # guide at: https://bundler.io/guides/creating_gem.html +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/rspec.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/rspec.tt new file mode 100644 index 0000000..34c5164 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/rspec.tt @@ -0,0 +1,3 @@ +--format documentation +--color +--require spec_helper diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/rubocop.yml.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/rubocop.yml.tt new file mode 100644 index 0000000..9ecec78 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/rubocop.yml.tt @@ -0,0 +1,13 @@ +AllCops: + TargetRubyVersion: <%= ::Gem::Version.new(config[:required_ruby_version]).segments[0..1].join(".") %> + +Style/StringLiterals: + Enabled: true + EnforcedStyle: double_quotes + +Style/StringLiteralsInInterpolation: + Enabled: true + EnforcedStyle: double_quotes + +Layout/LineLength: + Max: 120 diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/sig/newgem.rbs.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/sig/newgem.rbs.tt new file mode 100644 index 0000000..eb7b380 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/sig/newgem.rbs.tt @@ -0,0 +1,8 @@ +<%- config[:constant_array].each_with_index do |c, i| -%> +<%= " " * i %>module <%= c %> +<%- end -%> +<%= " " * config[:constant_array].size %>VERSION: String +<%= " " * config[:constant_array].size %># See the writing guide of rbs: https://github.com/ruby/rbs#guides +<%- (config[:constant_array].size-1).downto(0) do |i| -%> +<%= " " * i %>end +<%- end -%> diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/spec/newgem_spec.rb.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/spec/newgem_spec.rb.tt new file mode 100644 index 0000000..82cada9 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/spec/newgem_spec.rb.tt @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +RSpec.describe <%= config[:constant_name] %> do + it "has a version number" do + expect(<%= config[:constant_name] %>::VERSION).not_to be nil + end + + it "does something useful" do + expect(false).to eq(true) + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/spec/spec_helper.rb.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/spec/spec_helper.rb.tt new file mode 100644 index 0000000..70c6d1f --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/spec/spec_helper.rb.tt @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require "<%= config[:namespaced_path] %>" + +RSpec.configure do |config| + # Enable flags like --only-failures and --next-failure + config.example_status_persistence_file_path = ".rspec_status" + + # Disable RSpec exposing methods globally on `Module` and `main` + config.disable_monkey_patching! + + config.expect_with :rspec do |c| + c.syntax = :expect + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/standard.yml.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/standard.yml.tt new file mode 100644 index 0000000..934b0b2 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/standard.yml.tt @@ -0,0 +1,3 @@ +# For available configuration options, see: +# https://github.com/testdouble/standard +ruby_version: <%= ::Gem::Version.new(config[:required_ruby_version]).segments[0..1].join(".") %> diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/test/minitest/test_helper.rb.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/test/minitest/test_helper.rb.tt new file mode 100644 index 0000000..e05c387 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/test/minitest/test_helper.rb.tt @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../lib", __dir__) +require "<%= config[:namespaced_path] %>" + +require "minitest/autorun" diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt new file mode 100644 index 0000000..4b35a63 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require "test_helper" + +class <%= config[:minitest_constant_name] %> < Minitest::Test + def test_that_it_has_a_version_number + refute_nil ::<%= config[:constant_name] %>::VERSION + end + + def test_it_does_something_useful + assert false + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt new file mode 100644 index 0000000..5c61094 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require "test_helper" + +class <%= config[:constant_name] %>Test < Test::Unit::TestCase + test "VERSION" do + assert do + ::<%= config[:constant_name] %>.const_defined?(:VERSION) + end + end + + test "something useful" do + assert_equal("expected", "actual") + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt new file mode 100644 index 0000000..6f633c6 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../lib", __dir__) +require "<%= config[:namespaced_path] %>" + +require "test-unit" diff --git a/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/travis.yml.tt b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/travis.yml.tt new file mode 100644 index 0000000..eab16ad --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/templates/newgem/travis.yml.tt @@ -0,0 +1,6 @@ +--- +language: ruby +cache: bundler +rvm: + - <%= RUBY_VERSION %> +before_install: gem install bundler -v <%= Bundler::VERSION %> diff --git a/games/FNaFB2/Ruby/stdlib/bundler/ui.rb b/games/FNaFB2/Ruby/stdlib/bundler/ui.rb new file mode 100644 index 0000000..7a4fa03 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/ui.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Bundler + module UI + autoload :RGProxy, File.expand_path("ui/rg_proxy", __dir__) + autoload :Shell, File.expand_path("ui/shell", __dir__) + autoload :Silent, File.expand_path("ui/silent", __dir__) + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/ui/rg_proxy.rb b/games/FNaFB2/Ruby/stdlib/bundler/ui/rg_proxy.rb new file mode 100644 index 0000000..ef6def2 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/ui/rg_proxy.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require_relative "../ui" +require "rubygems/user_interaction" + +module Bundler + module UI + class RGProxy < ::Gem::SilentUI + def initialize(ui) + @ui = ui + super() + end + + def say(message) + @ui && @ui.debug(message) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/ui/shell.rb b/games/FNaFB2/Ruby/stdlib/bundler/ui/shell.rb new file mode 100644 index 0000000..384752a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/ui/shell.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: true + +require_relative "../vendored_thor" + +module Bundler + module UI + class Shell + LEVELS = %w[silent error warn confirm info debug].freeze + + attr_writer :shell + + def initialize(options = {}) + Thor::Base.shell = options["no-color"] ? Thor::Shell::Basic : nil + @shell = Thor::Base.shell.new + @level = ENV["DEBUG"] ? "debug" : "info" + @warning_history = [] + end + + def add_color(string, *color) + @shell.set_color(string, *color) + end + + def info(msg, newline = nil) + tell_me(msg, nil, newline) if level("info") + end + + def confirm(msg, newline = nil) + tell_me(msg, :green, newline) if level("confirm") + end + + def warn(msg, newline = nil, color = :yellow) + return unless level("warn") + return if @warning_history.include? msg + @warning_history << msg + + tell_err(msg, color, newline) + end + + def error(msg, newline = nil, color = :red) + return unless level("error") + tell_err(msg, color, newline) + end + + def debug(msg, newline = nil) + tell_me(msg, nil, newline) if debug? + end + + def debug? + level("debug") + end + + def quiet? + level("quiet") + end + + def ask(msg) + @shell.ask(msg) + end + + def yes?(msg) + @shell.yes?(msg) + end + + def no? + @shell.no?(msg) + end + + def level=(level) + raise ArgumentError unless LEVELS.include?(level.to_s) + @level = level.to_s + end + + def level(name = nil) + return @level unless name + unless index = LEVELS.index(name) + raise "#{name.inspect} is not a valid level" + end + index <= LEVELS.index(@level) + end + + def trace(e, newline = nil, force = false) + return unless debug? || force + msg = "#{e.class}: #{e.message}\n#{e.backtrace.join("\n ")}" + tell_err(msg, nil, newline) + end + + def silence(&blk) + with_level("silent", &blk) + end + + def unprinted_warnings + [] + end + + private + + # valimism + def tell_me(msg, color = nil, newline = nil) + msg = word_wrap(msg) if newline.is_a?(Hash) && newline[:wrap] + if newline.nil? + @shell.say(msg, color) + else + @shell.say(msg, color, newline) + end + end + + def tell_err(message, color = nil, newline = nil) + return if @shell.send(:stderr).closed? + + newline ||= message.to_s !~ /( |\t)\Z/ + message = word_wrap(message) if newline.is_a?(Hash) && newline[:wrap] + + color = nil if color && !$stderr.tty? + + buffer = @shell.send(:prepare_message, message, *color) + buffer << "\n" if newline && !message.to_s.end_with?("\n") + + @shell.send(:stderr).print(buffer) + @shell.send(:stderr).flush + end + + def strip_leading_spaces(text) + spaces = text[/\A\s+/, 0] + spaces ? text.gsub(/#{spaces}/, "") : text + end + + def word_wrap(text, line_width = @shell.terminal_width) + strip_leading_spaces(text).split("\n").collect do |line| + line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line + end * "\n" + end + + def with_level(level) + original = @level + @level = level + yield + ensure + @level = original + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/ui/silent.rb b/games/FNaFB2/Ruby/stdlib/bundler/ui/silent.rb new file mode 100644 index 0000000..dca1b2a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/ui/silent.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +module Bundler + module UI + class Silent + attr_writer :shell + + def initialize + @warnings = [] + end + + def add_color(string, color) + string + end + + def info(message, newline = nil) + end + + def confirm(message, newline = nil) + end + + def warn(message, newline = nil) + @warnings |= [message] + end + + def error(message, newline = nil) + end + + def debug(message, newline = nil) + end + + def debug? + false + end + + def quiet? + false + end + + def ask(message) + end + + def yes?(msg) + raise "Cannot ask yes? with a silent shell" + end + + def no? + raise "Cannot ask no? with a silent shell" + end + + def level=(name) + end + + def level(name = nil) + end + + def trace(message, newline = nil, force = false) + end + + def silence + yield + end + + def unprinted_warnings + @warnings + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/uri_credentials_filter.rb b/games/FNaFB2/Ruby/stdlib/bundler/uri_credentials_filter.rb new file mode 100644 index 0000000..ccfaf0b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/uri_credentials_filter.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Bundler + module URICredentialsFilter + module_function + + def credential_filtered_uri(uri_to_anonymize) + return uri_to_anonymize if uri_to_anonymize.nil? + uri = uri_to_anonymize.dup + if uri.is_a?(String) + return uri if File.exist?(uri) + + require_relative "vendored_uri" + uri = Bundler::URI(uri) + end + + if uri.userinfo + # oauth authentication + if uri.password == "x-oauth-basic" || uri.password == "x" + # URI as string does not display with password if no user is set + oauth_designation = uri.password + uri.user = oauth_designation + end + uri.password = nil + end + return uri.to_s if uri_to_anonymize.is_a?(String) + uri + rescue Bundler::URI::InvalidURIError # uri is not canonical uri scheme + uri + end + + def credential_filtered_string(str_to_filter, uri) + return str_to_filter if uri.nil? || str_to_filter.nil? + str_with_no_credentials = str_to_filter.dup + anonymous_uri_str = credential_filtered_uri(uri).to_s + uri_str = uri.to_s + if anonymous_uri_str != uri_str + str_with_no_credentials = str_with_no_credentials.gsub(uri_str, anonymous_uri_str) + end + str_with_no_credentials + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/connection_pool/lib/connection_pool.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/connection_pool/lib/connection_pool.rb new file mode 100644 index 0000000..984c1c3 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/connection_pool/lib/connection_pool.rb @@ -0,0 +1,126 @@ +require "timeout" +require_relative "connection_pool/version" + +class Bundler::ConnectionPool + class Error < ::RuntimeError; end + class PoolShuttingDownError < ::Bundler::ConnectionPool::Error; end + class TimeoutError < ::Timeout::Error; end +end + +# Generic connection pool class for sharing a limited number of objects or network connections +# among many threads. Note: pool elements are lazily created. +# +# Example usage with block (faster): +# +# @pool = Bundler::ConnectionPool.new { Redis.new } +# @pool.with do |redis| +# redis.lpop('my-list') if redis.llen('my-list') > 0 +# end +# +# Using optional timeout override (for that single invocation) +# +# @pool.with(timeout: 2.0) do |redis| +# redis.lpop('my-list') if redis.llen('my-list') > 0 +# end +# +# Example usage replacing an existing connection (slower): +# +# $redis = Bundler::ConnectionPool.wrap { Redis.new } +# +# def do_work +# $redis.lpop('my-list') if $redis.llen('my-list') > 0 +# end +# +# Accepts the following options: +# - :size - number of connections to pool, defaults to 5 +# - :timeout - amount of time to wait for a connection if none currently available, defaults to 5 seconds +# +class Bundler::ConnectionPool + DEFAULTS = {size: 5, timeout: 5} + + def self.wrap(options, &block) + Wrapper.new(options, &block) + end + + def initialize(options = {}, &block) + raise ArgumentError, "Connection pool requires a block" unless block + + options = DEFAULTS.merge(options) + + @size = Integer(options.fetch(:size)) + @timeout = options.fetch(:timeout) + + @available = TimedStack.new(@size, &block) + @key = :"pool-#{@available.object_id}" + @key_count = :"pool-#{@available.object_id}-count" + end + + def with(options = {}) + Thread.handle_interrupt(Exception => :never) do + conn = checkout(options) + begin + Thread.handle_interrupt(Exception => :immediate) do + yield conn + end + ensure + checkin + end + end + end + alias then with + + def checkout(options = {}) + if ::Thread.current[@key] + ::Thread.current[@key_count] += 1 + ::Thread.current[@key] + else + ::Thread.current[@key_count] = 1 + ::Thread.current[@key] = @available.pop(options[:timeout] || @timeout) + end + end + + def checkin + if ::Thread.current[@key] + if ::Thread.current[@key_count] == 1 + @available.push(::Thread.current[@key]) + ::Thread.current[@key] = nil + ::Thread.current[@key_count] = nil + else + ::Thread.current[@key_count] -= 1 + end + else + raise Bundler::ConnectionPool::Error, "no connections are checked out" + end + + nil + end + + ## + # Shuts down the Bundler::ConnectionPool by passing each connection to +block+ and + # then removing it from the pool. Attempting to checkout a connection after + # shutdown will raise +Bundler::ConnectionPool::PoolShuttingDownError+. + + def shutdown(&block) + @available.shutdown(&block) + end + + ## + # Reloads the Bundler::ConnectionPool by passing each connection to +block+ and then + # removing it the pool. Subsequent checkouts will create new connections as + # needed. + + def reload(&block) + @available.shutdown(reload: true, &block) + end + + # Size of this connection pool + attr_reader :size + + # Number of pool entries available for checkout at this instant. + def available + @available.length + end +end + +require_relative "connection_pool/timed_stack" +require_relative "connection_pool/wrapper" diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb new file mode 100644 index 0000000..a7b1cf0 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb @@ -0,0 +1,174 @@ +## +# The TimedStack manages a pool of homogeneous connections (or any resource +# you wish to manage). Connections are created lazily up to a given maximum +# number. + +# Examples: +# +# ts = TimedStack.new(1) { MyConnection.new } +# +# # fetch a connection +# conn = ts.pop +# +# # return a connection +# ts.push conn +# +# conn = ts.pop +# ts.pop timeout: 5 +# #=> raises Bundler::ConnectionPool::TimeoutError after 5 seconds + +class Bundler::ConnectionPool::TimedStack + attr_reader :max + + ## + # Creates a new pool with +size+ connections that are created from the given + # +block+. + + def initialize(size = 0, &block) + @create_block = block + @created = 0 + @que = [] + @max = size + @mutex = Thread::Mutex.new + @resource = Thread::ConditionVariable.new + @shutdown_block = nil + end + + ## + # Returns +obj+ to the stack. +options+ is ignored in TimedStack but may be + # used by subclasses that extend TimedStack. + + def push(obj, options = {}) + @mutex.synchronize do + if @shutdown_block + @shutdown_block.call(obj) + else + store_connection obj, options + end + + @resource.broadcast + end + end + alias << push + + ## + # Retrieves a connection from the stack. If a connection is available it is + # immediately returned. If no connection is available within the given + # timeout a Bundler::ConnectionPool::TimeoutError is raised. + # + # +:timeout+ is the only checked entry in +options+ and is preferred over + # the +timeout+ argument (which will be removed in a future release). Other + # options may be used by subclasses that extend TimedStack. + + def pop(timeout = 0.5, options = {}) + options, timeout = timeout, 0.5 if Hash === timeout + timeout = options.fetch :timeout, timeout + + deadline = current_time + timeout + @mutex.synchronize do + loop do + raise Bundler::ConnectionPool::PoolShuttingDownError if @shutdown_block + return fetch_connection(options) if connection_stored?(options) + + connection = try_create(options) + return connection if connection + + to_wait = deadline - current_time + raise Bundler::ConnectionPool::TimeoutError, "Waited #{timeout} sec" if to_wait <= 0 + @resource.wait(@mutex, to_wait) + end + end + end + + ## + # Shuts down the TimedStack by passing each connection to +block+ and then + # removing it from the pool. Attempting to checkout a connection after + # shutdown will raise +Bundler::ConnectionPool::PoolShuttingDownError+ unless + # +:reload+ is +true+. + + def shutdown(reload: false, &block) + raise ArgumentError, "shutdown must receive a block" unless block_given? + + @mutex.synchronize do + @shutdown_block = block + @resource.broadcast + + shutdown_connections + @shutdown_block = nil if reload + end + end + + ## + # Returns +true+ if there are no available connections. + + def empty? + (@created - @que.length) >= @max + end + + ## + # The number of connections available on the stack. + + def length + @max - @created + @que.length + end + + private + + def current_time + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end + + ## + # This is an extension point for TimedStack and is called with a mutex. + # + # This method must returns true if a connection is available on the stack. + + def connection_stored?(options = nil) + !@que.empty? + end + + ## + # This is an extension point for TimedStack and is called with a mutex. + # + # This method must return a connection from the stack. + + def fetch_connection(options = nil) + @que.pop + end + + ## + # This is an extension point for TimedStack and is called with a mutex. + # + # This method must shut down all connections on the stack. + + def shutdown_connections(options = nil) + while connection_stored?(options) + conn = fetch_connection(options) + @shutdown_block.call(conn) + end + @created = 0 + end + + ## + # This is an extension point for TimedStack and is called with a mutex. + # + # This method must return +obj+ to the stack. + + def store_connection(obj, options = nil) + @que.push obj + end + + ## + # This is an extension point for TimedStack and is called with a mutex. + # + # This method must create a connection if and only if the total number of + # connections allowed has not been met. + + def try_create(options = nil) + unless @created == @max + object = @create_block.call + @created += 1 + object + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/connection_pool/lib/connection_pool/version.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/connection_pool/lib/connection_pool/version.rb new file mode 100644 index 0000000..56ebf69 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/connection_pool/lib/connection_pool/version.rb @@ -0,0 +1,3 @@ +class Bundler::ConnectionPool + VERSION = "2.3.0" +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb new file mode 100644 index 0000000..880170c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb @@ -0,0 +1,57 @@ +class Bundler::ConnectionPool + class Wrapper < ::BasicObject + METHODS = [:with, :pool_shutdown, :wrapped_pool] + + def initialize(options = {}, &block) + @pool = options.fetch(:pool) { ::Bundler::ConnectionPool.new(options, &block) } + end + + def wrapped_pool + @pool + end + + def with(&block) + @pool.with(&block) + end + + def pool_shutdown(&block) + @pool.shutdown(&block) + end + + def pool_size + @pool.size + end + + def pool_available + @pool.available + end + + def respond_to?(id, *args) + METHODS.include?(id) || with { |c| c.respond_to?(id, *args) } + end + + # rubocop:disable Style/MethodMissingSuper + # rubocop:disable Style/MissingRespondToMissing + if ::RUBY_VERSION >= "3.0.0" + def method_missing(name, *args, **kwargs, &block) + with do |connection| + connection.send(name, *args, **kwargs, &block) + end + end + elsif ::RUBY_VERSION >= "2.7.0" + ruby2_keywords def method_missing(name, *args, &block) + with do |connection| + connection.send(name, *args, &block) + end + end + else + def method_missing(name, *args, &block) + with do |connection| + connection.send(name, *args, &block) + end + end + end + # rubocop:enable Style/MethodMissingSuper + # rubocop:enable Style/MissingRespondToMissing + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/fileutils/lib/fileutils.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/fileutils/lib/fileutils.rb new file mode 100644 index 0000000..8f8faf3 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/fileutils/lib/fileutils.rb @@ -0,0 +1,1764 @@ +# frozen_string_literal: true + +begin + require 'rbconfig' +rescue LoadError + # for make mjit-headers +end + +# +# = fileutils.rb +# +# Copyright (c) 2000-2007 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# +# == module Bundler::FileUtils +# +# Namespace for several file utility methods for copying, moving, removing, etc. +# +# === Module Functions +# +# require 'bundler/vendor/fileutils/lib/fileutils' +# +# Bundler::FileUtils.cd(dir, **options) +# Bundler::FileUtils.cd(dir, **options) {|dir| block } +# Bundler::FileUtils.pwd() +# Bundler::FileUtils.mkdir(dir, **options) +# Bundler::FileUtils.mkdir(list, **options) +# Bundler::FileUtils.mkdir_p(dir, **options) +# Bundler::FileUtils.mkdir_p(list, **options) +# Bundler::FileUtils.rmdir(dir, **options) +# Bundler::FileUtils.rmdir(list, **options) +# Bundler::FileUtils.ln(target, link, **options) +# Bundler::FileUtils.ln(targets, dir, **options) +# Bundler::FileUtils.ln_s(target, link, **options) +# Bundler::FileUtils.ln_s(targets, dir, **options) +# Bundler::FileUtils.ln_sf(target, link, **options) +# Bundler::FileUtils.cp(src, dest, **options) +# Bundler::FileUtils.cp(list, dir, **options) +# Bundler::FileUtils.cp_r(src, dest, **options) +# Bundler::FileUtils.cp_r(list, dir, **options) +# Bundler::FileUtils.mv(src, dest, **options) +# Bundler::FileUtils.mv(list, dir, **options) +# Bundler::FileUtils.rm(list, **options) +# Bundler::FileUtils.rm_r(list, **options) +# Bundler::FileUtils.rm_rf(list, **options) +# Bundler::FileUtils.install(src, dest, **options) +# Bundler::FileUtils.chmod(mode, list, **options) +# Bundler::FileUtils.chmod_R(mode, list, **options) +# Bundler::FileUtils.chown(user, group, list, **options) +# Bundler::FileUtils.chown_R(user, group, list, **options) +# Bundler::FileUtils.touch(list, **options) +# +# Possible options are: +# +# :force :: forced operation (rewrite files if exist, remove +# directories if not empty, etc.); +# :verbose :: print command to be run, in bash syntax, before +# performing it; +# :preserve :: preserve object's group, user and modification +# time on copying; +# :noop :: no changes are made (usable in combination with +# :verbose which will print the command to run) +# +# Each method documents the options that it honours. See also ::commands, +# ::options and ::options_of methods to introspect which command have which +# options. +# +# All methods that have the concept of a "source" file or directory can take +# either one file or a list of files in that argument. See the method +# documentation for examples. +# +# There are some `low level' methods, which do not accept keyword arguments: +# +# Bundler::FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) +# Bundler::FileUtils.copy_file(src, dest, preserve = false, dereference = true) +# Bundler::FileUtils.copy_stream(srcstream, deststream) +# Bundler::FileUtils.remove_entry(path, force = false) +# Bundler::FileUtils.remove_entry_secure(path, force = false) +# Bundler::FileUtils.remove_file(path, force = false) +# Bundler::FileUtils.compare_file(path_a, path_b) +# Bundler::FileUtils.compare_stream(stream_a, stream_b) +# Bundler::FileUtils.uptodate?(file, cmp_list) +# +# == module Bundler::FileUtils::Verbose +# +# This module has all methods of Bundler::FileUtils module, but it outputs messages +# before acting. This equates to passing the :verbose flag to methods +# in Bundler::FileUtils. +# +# == module Bundler::FileUtils::NoWrite +# +# This module has all methods of Bundler::FileUtils module, but never changes +# files/directories. This equates to passing the :noop flag to methods +# in Bundler::FileUtils. +# +# == module Bundler::FileUtils::DryRun +# +# This module has all methods of Bundler::FileUtils module, but never changes +# files/directories. This equates to passing the :noop and +# :verbose flags to methods in Bundler::FileUtils. +# +module Bundler::FileUtils + VERSION = "1.4.1" + + def self.private_module_function(name) #:nodoc: + module_function name + private_class_method name + end + + # + # Returns the name of the current directory. + # + def pwd + Dir.pwd + end + module_function :pwd + + alias getwd pwd + module_function :getwd + + # + # Changes the current directory to the directory +dir+. + # + # If this method is called with block, resumes to the previous + # working directory after the block execution has finished. + # + # Bundler::FileUtils.cd('/') # change directory + # + # Bundler::FileUtils.cd('/', verbose: true) # change directory and report it + # + # Bundler::FileUtils.cd('/') do # change directory + # # ... # do something + # end # return to original directory + # + def cd(dir, verbose: nil, &block) # :yield: dir + fu_output_message "cd #{dir}" if verbose + result = Dir.chdir(dir, &block) + fu_output_message 'cd -' if verbose and block + result + end + module_function :cd + + alias chdir cd + module_function :chdir + + # + # Returns true if +new+ is newer than all +old_list+. + # Non-existent files are older than any file. + # + # Bundler::FileUtils.uptodate?('hello.o', %w(hello.c hello.h)) or \ + # system 'make hello.o' + # + def uptodate?(new, old_list) + return false unless File.exist?(new) + new_time = File.mtime(new) + old_list.each do |old| + if File.exist?(old) + return false unless new_time > File.mtime(old) + end + end + true + end + module_function :uptodate? + + def remove_trailing_slash(dir) #:nodoc: + dir == '/' ? dir : dir.chomp(?/) + end + private_module_function :remove_trailing_slash + + # + # Creates one or more directories. + # + # Bundler::FileUtils.mkdir 'test' + # Bundler::FileUtils.mkdir %w(tmp data) + # Bundler::FileUtils.mkdir 'notexist', noop: true # Does not really create. + # Bundler::FileUtils.mkdir 'tmp', mode: 0700 + # + def mkdir(list, mode: nil, noop: nil, verbose: nil) + list = fu_list(list) + fu_output_message "mkdir #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}" if verbose + return if noop + + list.each do |dir| + fu_mkdir dir, mode + end + end + module_function :mkdir + + # + # Creates a directory and all its parent directories. + # For example, + # + # Bundler::FileUtils.mkdir_p '/usr/local/lib/ruby' + # + # causes to make following directories, if they do not exist. + # + # * /usr + # * /usr/local + # * /usr/local/lib + # * /usr/local/lib/ruby + # + # You can pass several directories at a time in a list. + # + def mkdir_p(list, mode: nil, noop: nil, verbose: nil) + list = fu_list(list) + fu_output_message "mkdir -p #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}" if verbose + return *list if noop + + list.map {|path| remove_trailing_slash(path)}.each do |path| + # optimize for the most common case + begin + fu_mkdir path, mode + next + rescue SystemCallError + next if File.directory?(path) + end + + stack = [] + until path == stack.last # dirname("/")=="/", dirname("C:/")=="C:/" + stack.push path + path = File.dirname(path) + end + stack.pop # root directory should exist + stack.reverse_each do |dir| + begin + fu_mkdir dir, mode + rescue SystemCallError + raise unless File.directory?(dir) + end + end + end + + return *list + end + module_function :mkdir_p + + alias mkpath mkdir_p + alias makedirs mkdir_p + module_function :mkpath + module_function :makedirs + + def fu_mkdir(path, mode) #:nodoc: + path = remove_trailing_slash(path) + if mode + Dir.mkdir path, mode + File.chmod mode, path + else + Dir.mkdir path + end + end + private_module_function :fu_mkdir + + # + # Removes one or more directories. + # + # Bundler::FileUtils.rmdir 'somedir' + # Bundler::FileUtils.rmdir %w(somedir anydir otherdir) + # # Does not really remove directory; outputs message. + # Bundler::FileUtils.rmdir 'somedir', verbose: true, noop: true + # + def rmdir(list, parents: nil, noop: nil, verbose: nil) + list = fu_list(list) + fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if verbose + return if noop + list.each do |dir| + Dir.rmdir(dir = remove_trailing_slash(dir)) + if parents + begin + until (parent = File.dirname(dir)) == '.' or parent == dir + dir = parent + Dir.rmdir(dir) + end + rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT + end + end + end + end + module_function :rmdir + + # + # :call-seq: + # Bundler::FileUtils.ln(target, link, force: nil, noop: nil, verbose: nil) + # Bundler::FileUtils.ln(target, dir, force: nil, noop: nil, verbose: nil) + # Bundler::FileUtils.ln(targets, dir, force: nil, noop: nil, verbose: nil) + # + # In the first form, creates a hard link +link+ which points to +target+. + # If +link+ already exists, raises Errno::EEXIST. + # But if the +force+ option is set, overwrites +link+. + # + # Bundler::FileUtils.ln 'gcc', 'cc', verbose: true + # Bundler::FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs' + # + # In the second form, creates a link +dir/target+ pointing to +target+. + # In the third form, creates several hard links in the directory +dir+, + # pointing to each item in +targets+. + # If +dir+ is not a directory, raises Errno::ENOTDIR. + # + # Bundler::FileUtils.cd '/sbin' + # Bundler::FileUtils.ln %w(cp mv mkdir), '/bin' # Now /sbin/cp and /bin/cp are linked. + # + def ln(src, dest, force: nil, noop: nil, verbose: nil) + fu_output_message "ln#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose + return if noop + fu_each_src_dest0(src, dest) do |s,d| + remove_file d, true if force + File.link s, d + end + end + module_function :ln + + alias link ln + module_function :link + + # + # Hard link +src+ to +dest+. If +src+ is a directory, this method links + # all its contents recursively. If +dest+ is a directory, links + # +src+ to +dest/src+. + # + # +src+ can be a list of files. + # + # If +dereference_root+ is true, this method dereference tree root. + # + # If +remove_destination+ is true, this method removes each destination file before copy. + # + # Bundler::FileUtils.rm_r site_ruby + '/mylib', force: true + # Bundler::FileUtils.cp_lr 'lib/', site_ruby + '/mylib' + # + # # Examples of linking several files to target directory. + # Bundler::FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail' + # Bundler::FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', noop: true, verbose: true + # + # # If you want to link all contents of a directory instead of the + # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y, + # # use the following code. + # Bundler::FileUtils.cp_lr 'src/.', 'dest' # cp_lr('src', 'dest') makes dest/src, but this doesn't. + # + def cp_lr(src, dest, noop: nil, verbose: nil, + dereference_root: true, remove_destination: false) + fu_output_message "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose + return if noop + fu_each_src_dest(src, dest) do |s, d| + link_entry s, d, dereference_root, remove_destination + end + end + module_function :cp_lr + + # + # :call-seq: + # Bundler::FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil) + # Bundler::FileUtils.ln_s(target, dir, force: nil, noop: nil, verbose: nil) + # Bundler::FileUtils.ln_s(targets, dir, force: nil, noop: nil, verbose: nil) + # + # In the first form, creates a symbolic link +link+ which points to +target+. + # If +link+ already exists, raises Errno::EEXIST. + # But if the force option is set, overwrites +link+. + # + # Bundler::FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby' + # Bundler::FileUtils.ln_s 'verylongsourcefilename.c', 'c', force: true + # + # In the second form, creates a link +dir/target+ pointing to +target+. + # In the third form, creates several symbolic links in the directory +dir+, + # pointing to each item in +targets+. + # If +dir+ is not a directory, raises Errno::ENOTDIR. + # + # Bundler::FileUtils.ln_s Dir.glob('/bin/*.rb'), '/home/foo/bin' + # + def ln_s(src, dest, force: nil, noop: nil, verbose: nil) + fu_output_message "ln -s#{force ? 'f' : ''} #{[src,dest].flatten.join ' '}" if verbose + return if noop + fu_each_src_dest0(src, dest) do |s,d| + remove_file d, true if force + File.symlink s, d + end + end + module_function :ln_s + + alias symlink ln_s + module_function :symlink + + # + # :call-seq: + # Bundler::FileUtils.ln_sf(*args) + # + # Same as + # + # Bundler::FileUtils.ln_s(*args, force: true) + # + def ln_sf(src, dest, noop: nil, verbose: nil) + ln_s src, dest, force: true, noop: noop, verbose: verbose + end + module_function :ln_sf + + # + # Hard links a file system entry +src+ to +dest+. + # If +src+ is a directory, this method links its contents recursively. + # + # Both of +src+ and +dest+ must be a path name. + # +src+ must exist, +dest+ must not exist. + # + # If +dereference_root+ is true, this method dereferences the tree root. + # + # If +remove_destination+ is true, this method removes each destination file before copy. + # + def link_entry(src, dest, dereference_root = false, remove_destination = false) + Entry_.new(src, nil, dereference_root).traverse do |ent| + destent = Entry_.new(dest, ent.rel, false) + File.unlink destent.path if remove_destination && File.file?(destent.path) + ent.link destent.path + end + end + module_function :link_entry + + # + # Copies a file content +src+ to +dest+. If +dest+ is a directory, + # copies +src+ to +dest/src+. + # + # If +src+ is a list of files, then +dest+ must be a directory. + # + # Bundler::FileUtils.cp 'eval.c', 'eval.c.org' + # Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6' + # Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', verbose: true + # Bundler::FileUtils.cp 'symlink', 'dest' # copy content, "dest" is not a symlink + # + def cp(src, dest, preserve: nil, noop: nil, verbose: nil) + fu_output_message "cp#{preserve ? ' -p' : ''} #{[src,dest].flatten.join ' '}" if verbose + return if noop + fu_each_src_dest(src, dest) do |s, d| + copy_file s, d, preserve + end + end + module_function :cp + + alias copy cp + module_function :copy + + # + # Copies +src+ to +dest+. If +src+ is a directory, this method copies + # all its contents recursively. If +dest+ is a directory, copies + # +src+ to +dest/src+. + # + # +src+ can be a list of files. + # + # If +dereference_root+ is true, this method dereference tree root. + # + # If +remove_destination+ is true, this method removes each destination file before copy. + # + # # Installing Ruby library "mylib" under the site_ruby + # Bundler::FileUtils.rm_r site_ruby + '/mylib', force: true + # Bundler::FileUtils.cp_r 'lib/', site_ruby + '/mylib' + # + # # Examples of copying several files to target directory. + # Bundler::FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail' + # Bundler::FileUtils.cp_r Dir.glob('*.rb'), '/home/foo/lib/ruby', noop: true, verbose: true + # + # # If you want to copy all contents of a directory instead of the + # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y, + # # use following code. + # Bundler::FileUtils.cp_r 'src/.', 'dest' # cp_r('src', 'dest') makes dest/src, + # # but this doesn't. + # + def cp_r(src, dest, preserve: nil, noop: nil, verbose: nil, + dereference_root: true, remove_destination: nil) + fu_output_message "cp -r#{preserve ? 'p' : ''}#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose + return if noop + fu_each_src_dest(src, dest) do |s, d| + copy_entry s, d, preserve, dereference_root, remove_destination + end + end + module_function :cp_r + + # + # Copies a file system entry +src+ to +dest+. + # If +src+ is a directory, this method copies its contents recursively. + # This method preserves file types, c.f. symlink, directory... + # (FIFO, device files and etc. are not supported yet) + # + # Both of +src+ and +dest+ must be a path name. + # +src+ must exist, +dest+ must not exist. + # + # If +preserve+ is true, this method preserves owner, group, and + # modified time. Permissions are copied regardless +preserve+. + # + # If +dereference_root+ is true, this method dereference tree root. + # + # If +remove_destination+ is true, this method removes each destination file before copy. + # + def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) + if dereference_root + src = File.realpath(src) + end + + Entry_.new(src, nil, false).wrap_traverse(proc do |ent| + destent = Entry_.new(dest, ent.rel, false) + File.unlink destent.path if remove_destination && (File.file?(destent.path) || File.symlink?(destent.path)) + ent.copy destent.path + end, proc do |ent| + destent = Entry_.new(dest, ent.rel, false) + ent.copy_metadata destent.path if preserve + end) + end + module_function :copy_entry + + # + # Copies file contents of +src+ to +dest+. + # Both of +src+ and +dest+ must be a path name. + # + def copy_file(src, dest, preserve = false, dereference = true) + ent = Entry_.new(src, nil, dereference) + ent.copy_file dest + ent.copy_metadata dest if preserve + end + module_function :copy_file + + # + # Copies stream +src+ to +dest+. + # +src+ must respond to #read(n) and + # +dest+ must respond to #write(str). + # + def copy_stream(src, dest) + IO.copy_stream(src, dest) + end + module_function :copy_stream + + # + # Moves file(s) +src+ to +dest+. If +file+ and +dest+ exist on the different + # disk partition, the file is copied then the original file is removed. + # + # Bundler::FileUtils.mv 'badname.rb', 'goodname.rb' + # Bundler::FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', force: true # no error + # + # Bundler::FileUtils.mv %w(junk.txt dust.txt), '/home/foo/.trash/' + # Bundler::FileUtils.mv Dir.glob('test*.rb'), 'test', noop: true, verbose: true + # + def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil) + fu_output_message "mv#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose + return if noop + fu_each_src_dest(src, dest) do |s, d| + destent = Entry_.new(d, nil, true) + begin + if destent.exist? + if destent.directory? + raise Errno::EEXIST, d + end + end + begin + File.rename s, d + rescue Errno::EXDEV, + Errno::EPERM # move from unencrypted to encrypted dir (ext4) + copy_entry s, d, true + if secure + remove_entry_secure s, force + else + remove_entry s, force + end + end + rescue SystemCallError + raise unless force + end + end + end + module_function :mv + + alias move mv + module_function :move + + # + # Remove file(s) specified in +list+. This method cannot remove directories. + # All StandardErrors are ignored when the :force option is set. + # + # Bundler::FileUtils.rm %w( junk.txt dust.txt ) + # Bundler::FileUtils.rm Dir.glob('*.so') + # Bundler::FileUtils.rm 'NotExistFile', force: true # never raises exception + # + def rm(list, force: nil, noop: nil, verbose: nil) + list = fu_list(list) + fu_output_message "rm#{force ? ' -f' : ''} #{list.join ' '}" if verbose + return if noop + + list.each do |path| + remove_file path, force + end + end + module_function :rm + + alias remove rm + module_function :remove + + # + # Equivalent to + # + # Bundler::FileUtils.rm(list, force: true) + # + def rm_f(list, noop: nil, verbose: nil) + rm list, force: true, noop: noop, verbose: verbose + end + module_function :rm_f + + alias safe_unlink rm_f + module_function :safe_unlink + + # + # remove files +list+[0] +list+[1]... If +list+[n] is a directory, + # removes its all contents recursively. This method ignores + # StandardError when :force option is set. + # + # Bundler::FileUtils.rm_r Dir.glob('/tmp/*') + # Bundler::FileUtils.rm_r 'some_dir', force: true + # + # WARNING: This method causes local vulnerability + # if one of parent directories or removing directory tree are world + # writable (including /tmp, whose permission is 1777), and the current + # process has strong privilege such as Unix super user (root), and the + # system has symbolic link. For secure removing, read the documentation + # of remove_entry_secure carefully, and set :secure option to true. + # Default is secure: false. + # + # NOTE: This method calls remove_entry_secure if :secure option is set. + # See also remove_entry_secure. + # + def rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil) + list = fu_list(list) + fu_output_message "rm -r#{force ? 'f' : ''} #{list.join ' '}" if verbose + return if noop + list.each do |path| + if secure + remove_entry_secure path, force + else + remove_entry path, force + end + end + end + module_function :rm_r + + # + # Equivalent to + # + # Bundler::FileUtils.rm_r(list, force: true) + # + # WARNING: This method causes local vulnerability. + # Read the documentation of rm_r first. + # + def rm_rf(list, noop: nil, verbose: nil, secure: nil) + rm_r list, force: true, noop: noop, verbose: verbose, secure: secure + end + module_function :rm_rf + + alias rmtree rm_rf + module_function :rmtree + + # + # This method removes a file system entry +path+. +path+ shall be a + # regular file, a directory, or something. If +path+ is a directory, + # remove it recursively. This method is required to avoid TOCTTOU + # (time-of-check-to-time-of-use) local security vulnerability of rm_r. + # #rm_r causes security hole when: + # + # * Parent directory is world writable (including /tmp). + # * Removing directory tree includes world writable directory. + # * The system has symbolic link. + # + # To avoid this security hole, this method applies special preprocess. + # If +path+ is a directory, this method chown(2) and chmod(2) all + # removing directories. This requires the current process is the + # owner of the removing whole directory tree, or is the super user (root). + # + # WARNING: You must ensure that *ALL* parent directories cannot be + # moved by other untrusted users. For example, parent directories + # should not be owned by untrusted users, and should not be world + # writable except when the sticky bit set. + # + # WARNING: Only the owner of the removing directory tree, or Unix super + # user (root) should invoke this method. Otherwise this method does not + # work. + # + # For details of this security vulnerability, see Perl's case: + # + # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448 + # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452 + # + # For fileutils.rb, this vulnerability is reported in [ruby-dev:26100]. + # + def remove_entry_secure(path, force = false) + unless fu_have_symlink? + remove_entry path, force + return + end + fullpath = File.expand_path(path) + st = File.lstat(fullpath) + unless st.directory? + File.unlink fullpath + return + end + # is a directory. + parent_st = File.stat(File.dirname(fullpath)) + unless parent_st.world_writable? + remove_entry path, force + return + end + unless parent_st.sticky? + raise ArgumentError, "parent directory is world writable, Bundler::FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})" + end + + # freeze tree root + euid = Process.euid + dot_file = fullpath + "/." + begin + File.open(dot_file) {|f| + unless fu_stat_identical_entry?(st, f.stat) + # symlink (TOC-to-TOU attack?) + File.unlink fullpath + return + end + f.chown euid, -1 + f.chmod 0700 + } + rescue Errno::EISDIR # JRuby in non-native mode can't open files as dirs + File.lstat(dot_file).tap {|fstat| + unless fu_stat_identical_entry?(st, fstat) + # symlink (TOC-to-TOU attack?) + File.unlink fullpath + return + end + File.chown euid, -1, dot_file + File.chmod 0700, dot_file + } + end + + unless fu_stat_identical_entry?(st, File.lstat(fullpath)) + # TOC-to-TOU attack? + File.unlink fullpath + return + end + + # ---- tree root is frozen ---- + root = Entry_.new(path) + root.preorder_traverse do |ent| + if ent.directory? + ent.chown euid, -1 + ent.chmod 0700 + end + end + root.postorder_traverse do |ent| + begin + ent.remove + rescue + raise unless force + end + end + rescue + raise unless force + end + module_function :remove_entry_secure + + def fu_have_symlink? #:nodoc: + File.symlink nil, nil + rescue NotImplementedError + return false + rescue TypeError + return true + end + private_module_function :fu_have_symlink? + + def fu_stat_identical_entry?(a, b) #:nodoc: + a.dev == b.dev and a.ino == b.ino + end + private_module_function :fu_stat_identical_entry? + + # + # This method removes a file system entry +path+. + # +path+ might be a regular file, a directory, or something. + # If +path+ is a directory, remove it recursively. + # + # See also remove_entry_secure. + # + def remove_entry(path, force = false) + Entry_.new(path).postorder_traverse do |ent| + begin + ent.remove + rescue + raise unless force + end + end + rescue + raise unless force + end + module_function :remove_entry + + # + # Removes a file +path+. + # This method ignores StandardError if +force+ is true. + # + def remove_file(path, force = false) + Entry_.new(path).remove_file + rescue + raise unless force + end + module_function :remove_file + + # + # Removes a directory +dir+ and its contents recursively. + # This method ignores StandardError if +force+ is true. + # + def remove_dir(path, force = false) + remove_entry path, force # FIXME?? check if it is a directory + end + module_function :remove_dir + + # + # Returns true if the contents of a file +a+ and a file +b+ are identical. + # + # Bundler::FileUtils.compare_file('somefile', 'somefile') #=> true + # Bundler::FileUtils.compare_file('/dev/null', '/dev/urandom') #=> false + # + def compare_file(a, b) + return false unless File.size(a) == File.size(b) + File.open(a, 'rb') {|fa| + File.open(b, 'rb') {|fb| + return compare_stream(fa, fb) + } + } + end + module_function :compare_file + + alias identical? compare_file + alias cmp compare_file + module_function :identical? + module_function :cmp + + # + # Returns true if the contents of a stream +a+ and +b+ are identical. + # + def compare_stream(a, b) + bsize = fu_stream_blksize(a, b) + + if RUBY_VERSION > "2.4" + sa = String.new(capacity: bsize) + sb = String.new(capacity: bsize) + else + sa = String.new + sb = String.new + end + + begin + a.read(bsize, sa) + b.read(bsize, sb) + return true if sa.empty? && sb.empty? + end while sa == sb + false + end + module_function :compare_stream + + # + # If +src+ is not same as +dest+, copies it and changes the permission + # mode to +mode+. If +dest+ is a directory, destination is +dest+/+src+. + # This method removes destination before copy. + # + # Bundler::FileUtils.install 'ruby', '/usr/local/bin/ruby', mode: 0755, verbose: true + # Bundler::FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', verbose: true + # + def install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil, + noop: nil, verbose: nil) + if verbose + msg = +"install -c" + msg << ' -p' if preserve + msg << ' -m ' << mode_to_s(mode) if mode + msg << " -o #{owner}" if owner + msg << " -g #{group}" if group + msg << ' ' << [src,dest].flatten.join(' ') + fu_output_message msg + end + return if noop + uid = fu_get_uid(owner) + gid = fu_get_gid(group) + fu_each_src_dest(src, dest) do |s, d| + st = File.stat(s) + unless File.exist?(d) and compare_file(s, d) + remove_file d, true + copy_file s, d + File.utime st.atime, st.mtime, d if preserve + File.chmod fu_mode(mode, st), d if mode + File.chown uid, gid, d if uid or gid + end + end + end + module_function :install + + def user_mask(target) #:nodoc: + target.each_char.inject(0) do |mask, chr| + case chr + when "u" + mask | 04700 + when "g" + mask | 02070 + when "o" + mask | 01007 + when "a" + mask | 07777 + else + raise ArgumentError, "invalid `who' symbol in file mode: #{chr}" + end + end + end + private_module_function :user_mask + + def apply_mask(mode, user_mask, op, mode_mask) #:nodoc: + case op + when '=' + (mode & ~user_mask) | (user_mask & mode_mask) + when '+' + mode | (user_mask & mode_mask) + when '-' + mode & ~(user_mask & mode_mask) + end + end + private_module_function :apply_mask + + def symbolic_modes_to_i(mode_sym, path) #:nodoc: + mode = if File::Stat === path + path.mode + else + File.stat(path).mode + end + mode_sym.split(/,/).inject(mode & 07777) do |current_mode, clause| + target, *actions = clause.split(/([=+-])/) + raise ArgumentError, "invalid file mode: #{mode_sym}" if actions.empty? + target = 'a' if target.empty? + user_mask = user_mask(target) + actions.each_slice(2) do |op, perm| + need_apply = op == '=' + mode_mask = (perm || '').each_char.inject(0) do |mask, chr| + case chr + when "r" + mask | 0444 + when "w" + mask | 0222 + when "x" + mask | 0111 + when "X" + if FileTest.directory? path + mask | 0111 + else + mask + end + when "s" + mask | 06000 + when "t" + mask | 01000 + when "u", "g", "o" + if mask.nonzero? + current_mode = apply_mask(current_mode, user_mask, op, mask) + end + need_apply = false + copy_mask = user_mask(chr) + (current_mode & copy_mask) / (copy_mask & 0111) * (user_mask & 0111) + else + raise ArgumentError, "invalid `perm' symbol in file mode: #{chr}" + end + end + + if mode_mask.nonzero? || need_apply + current_mode = apply_mask(current_mode, user_mask, op, mode_mask) + end + end + current_mode + end + end + private_module_function :symbolic_modes_to_i + + def fu_mode(mode, path) #:nodoc: + mode.is_a?(String) ? symbolic_modes_to_i(mode, path) : mode + end + private_module_function :fu_mode + + def mode_to_s(mode) #:nodoc: + mode.is_a?(String) ? mode : "%o" % mode + end + private_module_function :mode_to_s + + # + # Changes permission bits on the named files (in +list+) to the bit pattern + # represented by +mode+. + # + # +mode+ is the symbolic and absolute mode can be used. + # + # Absolute mode is + # Bundler::FileUtils.chmod 0755, 'somecommand' + # Bundler::FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb) + # Bundler::FileUtils.chmod 0755, '/usr/bin/ruby', verbose: true + # + # Symbolic mode is + # Bundler::FileUtils.chmod "u=wrx,go=rx", 'somecommand' + # Bundler::FileUtils.chmod "u=wr,go=rr", %w(my.rb your.rb his.rb her.rb) + # Bundler::FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', verbose: true + # + # "a" :: is user, group, other mask. + # "u" :: is user's mask. + # "g" :: is group's mask. + # "o" :: is other's mask. + # "w" :: is write permission. + # "r" :: is read permission. + # "x" :: is execute permission. + # "X" :: + # is execute permission for directories only, must be used in conjunction with "+" + # "s" :: is uid, gid. + # "t" :: is sticky bit. + # "+" :: is added to a class given the specified mode. + # "-" :: Is removed from a given class given mode. + # "=" :: Is the exact nature of the class will be given a specified mode. + + def chmod(mode, list, noop: nil, verbose: nil) + list = fu_list(list) + fu_output_message sprintf('chmod %s %s', mode_to_s(mode), list.join(' ')) if verbose + return if noop + list.each do |path| + Entry_.new(path).chmod(fu_mode(mode, path)) + end + end + module_function :chmod + + # + # Changes permission bits on the named files (in +list+) + # to the bit pattern represented by +mode+. + # + # Bundler::FileUtils.chmod_R 0700, "/tmp/app.#{$$}" + # Bundler::FileUtils.chmod_R "u=wrx", "/tmp/app.#{$$}" + # + def chmod_R(mode, list, noop: nil, verbose: nil, force: nil) + list = fu_list(list) + fu_output_message sprintf('chmod -R%s %s %s', + (force ? 'f' : ''), + mode_to_s(mode), list.join(' ')) if verbose + return if noop + list.each do |root| + Entry_.new(root).traverse do |ent| + begin + ent.chmod(fu_mode(mode, ent.path)) + rescue + raise unless force + end + end + end + end + module_function :chmod_R + + # + # Changes owner and group on the named files (in +list+) + # to the user +user+ and the group +group+. +user+ and +group+ + # may be an ID (Integer/String) or a name (String). + # If +user+ or +group+ is nil, this method does not change + # the attribute. + # + # Bundler::FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby' + # Bundler::FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), verbose: true + # + def chown(user, group, list, noop: nil, verbose: nil) + list = fu_list(list) + fu_output_message sprintf('chown %s %s', + (group ? "#{user}:#{group}" : user || ':'), + list.join(' ')) if verbose + return if noop + uid = fu_get_uid(user) + gid = fu_get_gid(group) + list.each do |path| + Entry_.new(path).chown uid, gid + end + end + module_function :chown + + # + # Changes owner and group on the named files (in +list+) + # to the user +user+ and the group +group+ recursively. + # +user+ and +group+ may be an ID (Integer/String) or + # a name (String). If +user+ or +group+ is nil, this + # method does not change the attribute. + # + # Bundler::FileUtils.chown_R 'www', 'www', '/var/www/htdocs' + # Bundler::FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', verbose: true + # + def chown_R(user, group, list, noop: nil, verbose: nil, force: nil) + list = fu_list(list) + fu_output_message sprintf('chown -R%s %s %s', + (force ? 'f' : ''), + (group ? "#{user}:#{group}" : user || ':'), + list.join(' ')) if verbose + return if noop + uid = fu_get_uid(user) + gid = fu_get_gid(group) + list.each do |root| + Entry_.new(root).traverse do |ent| + begin + ent.chown uid, gid + rescue + raise unless force + end + end + end + end + module_function :chown_R + + def fu_get_uid(user) #:nodoc: + return nil unless user + case user + when Integer + user + when /\A\d+\z/ + user.to_i + else + require 'etc' + Etc.getpwnam(user) ? Etc.getpwnam(user).uid : nil + end + end + private_module_function :fu_get_uid + + def fu_get_gid(group) #:nodoc: + return nil unless group + case group + when Integer + group + when /\A\d+\z/ + group.to_i + else + require 'etc' + Etc.getgrnam(group) ? Etc.getgrnam(group).gid : nil + end + end + private_module_function :fu_get_gid + + # + # Updates modification time (mtime) and access time (atime) of file(s) in + # +list+. Files are created if they don't exist. + # + # Bundler::FileUtils.touch 'timestamp' + # Bundler::FileUtils.touch Dir.glob('*.c'); system 'make' + # + def touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil) + list = fu_list(list) + t = mtime + if verbose + fu_output_message "touch #{nocreate ? '-c ' : ''}#{t ? t.strftime('-t %Y%m%d%H%M.%S ') : ''}#{list.join ' '}" + end + return if noop + list.each do |path| + created = nocreate + begin + File.utime(t, t, path) + rescue Errno::ENOENT + raise if created + File.open(path, 'a') { + ; + } + created = true + retry if t + end + end + end + module_function :touch + + private + + module StreamUtils_ + private + + case (defined?(::RbConfig) ? ::RbConfig::CONFIG['host_os'] : ::RUBY_PLATFORM) + when /mswin|mingw/ + def fu_windows?; true end + else + def fu_windows?; false end + end + + def fu_copy_stream0(src, dest, blksize = nil) #:nodoc: + IO.copy_stream(src, dest) + end + + def fu_stream_blksize(*streams) + streams.each do |s| + next unless s.respond_to?(:stat) + size = fu_blksize(s.stat) + return size if size + end + fu_default_blksize() + end + + def fu_blksize(st) + s = st.blksize + return nil unless s + return nil if s == 0 + s + end + + def fu_default_blksize + 1024 + end + end + + include StreamUtils_ + extend StreamUtils_ + + class Entry_ #:nodoc: internal use only + include StreamUtils_ + + def initialize(a, b = nil, deref = false) + @prefix = @rel = @path = nil + if b + @prefix = a + @rel = b + else + @path = a + end + @deref = deref + @stat = nil + @lstat = nil + end + + def inspect + "\#<#{self.class} #{path()}>" + end + + def path + if @path + File.path(@path) + else + join(@prefix, @rel) + end + end + + def prefix + @prefix || @path + end + + def rel + @rel + end + + def dereference? + @deref + end + + def exist? + begin + lstat + true + rescue Errno::ENOENT + false + end + end + + def file? + s = lstat! + s and s.file? + end + + def directory? + s = lstat! + s and s.directory? + end + + def symlink? + s = lstat! + s and s.symlink? + end + + def chardev? + s = lstat! + s and s.chardev? + end + + def blockdev? + s = lstat! + s and s.blockdev? + end + + def socket? + s = lstat! + s and s.socket? + end + + def pipe? + s = lstat! + s and s.pipe? + end + + S_IF_DOOR = 0xD000 + + def door? + s = lstat! + s and (s.mode & 0xF000 == S_IF_DOOR) + end + + def entries + opts = {} + opts[:encoding] = ::Encoding::UTF_8 if fu_windows? + + files = if Dir.respond_to?(:children) + Dir.children(path, **opts) + else + Dir.entries(path(), **opts) + .reject {|n| n == '.' or n == '..' } + end + + untaint = RUBY_VERSION < '2.7' + files.map {|n| Entry_.new(prefix(), join(rel(), untaint ? n.untaint : n)) } + end + + def stat + return @stat if @stat + if lstat() and lstat().symlink? + @stat = File.stat(path()) + else + @stat = lstat() + end + @stat + end + + def stat! + return @stat if @stat + if lstat! and lstat!.symlink? + @stat = File.stat(path()) + else + @stat = lstat! + end + @stat + rescue SystemCallError + nil + end + + def lstat + if dereference? + @lstat ||= File.stat(path()) + else + @lstat ||= File.lstat(path()) + end + end + + def lstat! + lstat() + rescue SystemCallError + nil + end + + def chmod(mode) + if symlink? + File.lchmod mode, path() if have_lchmod? + else + File.chmod mode, path() + end + end + + def chown(uid, gid) + if symlink? + File.lchown uid, gid, path() if have_lchown? + else + File.chown uid, gid, path() + end + end + + def link(dest) + case + when directory? + if !File.exist?(dest) and descendant_directory?(dest, path) + raise ArgumentError, "cannot link directory %s to itself %s" % [path, dest] + end + begin + Dir.mkdir dest + rescue + raise unless File.directory?(dest) + end + else + File.link path(), dest + end + end + + def copy(dest) + lstat + case + when file? + copy_file dest + when directory? + if !File.exist?(dest) and descendant_directory?(dest, path) + raise ArgumentError, "cannot copy directory %s to itself %s" % [path, dest] + end + begin + Dir.mkdir dest + rescue + raise unless File.directory?(dest) + end + when symlink? + File.symlink File.readlink(path()), dest + when chardev?, blockdev? + raise "cannot handle device file" + when socket? + begin + require 'socket' + rescue LoadError + raise "cannot handle socket" + else + raise "cannot handle socket" unless defined?(UNIXServer) + end + UNIXServer.new(dest).close + File.chmod lstat().mode, dest + when pipe? + raise "cannot handle FIFO" unless File.respond_to?(:mkfifo) + File.mkfifo dest, lstat().mode + when door? + raise "cannot handle door: #{path()}" + else + raise "unknown file type: #{path()}" + end + end + + def copy_file(dest) + File.open(path()) do |s| + File.open(dest, 'wb', s.stat.mode) do |f| + IO.copy_stream(s, f) + end + end + end + + def copy_metadata(path) + st = lstat() + if !st.symlink? + File.utime st.atime, st.mtime, path + end + mode = st.mode + begin + if st.symlink? + begin + File.lchown st.uid, st.gid, path + rescue NotImplementedError + end + else + File.chown st.uid, st.gid, path + end + rescue Errno::EPERM, Errno::EACCES + # clear setuid/setgid + mode &= 01777 + end + if st.symlink? + begin + File.lchmod mode, path + rescue NotImplementedError + end + else + File.chmod mode, path + end + end + + def remove + if directory? + remove_dir1 + else + remove_file + end + end + + def remove_dir1 + platform_support { + Dir.rmdir path().chomp(?/) + } + end + + def remove_file + platform_support { + File.unlink path + } + end + + def platform_support + return yield unless fu_windows? + first_time_p = true + begin + yield + rescue Errno::ENOENT + raise + rescue => err + if first_time_p + first_time_p = false + begin + File.chmod 0700, path() # Windows does not have symlink + retry + rescue SystemCallError + end + end + raise err + end + end + + def preorder_traverse + stack = [self] + while ent = stack.pop + yield ent + stack.concat ent.entries.reverse if ent.directory? + end + end + + alias traverse preorder_traverse + + def postorder_traverse + if directory? + entries().each do |ent| + ent.postorder_traverse do |e| + yield e + end + end + end + ensure + yield self + end + + def wrap_traverse(pre, post) + pre.call self + if directory? + entries.each do |ent| + ent.wrap_traverse pre, post + end + end + post.call self + end + + private + + @@fileutils_rb_have_lchmod = nil + + def have_lchmod? + # This is not MT-safe, but it does not matter. + if @@fileutils_rb_have_lchmod == nil + @@fileutils_rb_have_lchmod = check_have_lchmod? + end + @@fileutils_rb_have_lchmod + end + + def check_have_lchmod? + return false unless File.respond_to?(:lchmod) + File.lchmod 0 + return true + rescue NotImplementedError + return false + end + + @@fileutils_rb_have_lchown = nil + + def have_lchown? + # This is not MT-safe, but it does not matter. + if @@fileutils_rb_have_lchown == nil + @@fileutils_rb_have_lchown = check_have_lchown? + end + @@fileutils_rb_have_lchown + end + + def check_have_lchown? + return false unless File.respond_to?(:lchown) + File.lchown nil, nil + return true + rescue NotImplementedError + return false + end + + def join(dir, base) + return File.path(dir) if not base or base == '.' + return File.path(base) if not dir or dir == '.' + File.join(dir, base) + end + + if File::ALT_SEPARATOR + DIRECTORY_TERM = "(?=[/#{Regexp.quote(File::ALT_SEPARATOR)}]|\\z)" + else + DIRECTORY_TERM = "(?=/|\\z)" + end + + def descendant_directory?(descendant, ascendant) + if File::FNM_SYSCASE.nonzero? + File.expand_path(File.dirname(descendant)).casecmp(File.expand_path(ascendant)) == 0 + else + File.expand_path(File.dirname(descendant)) == File.expand_path(ascendant) + end + end + end # class Entry_ + + def fu_list(arg) #:nodoc: + [arg].flatten.map {|path| File.path(path) } + end + private_module_function :fu_list + + def fu_each_src_dest(src, dest) #:nodoc: + fu_each_src_dest0(src, dest) do |s, d| + raise ArgumentError, "same file: #{s} and #{d}" if fu_same?(s, d) + yield s, d + end + end + private_module_function :fu_each_src_dest + + def fu_each_src_dest0(src, dest) #:nodoc: + if tmp = Array.try_convert(src) + tmp.each do |s| + s = File.path(s) + yield s, File.join(dest, File.basename(s)) + end + else + src = File.path(src) + if File.directory?(dest) + yield src, File.join(dest, File.basename(src)) + else + yield src, File.path(dest) + end + end + end + private_module_function :fu_each_src_dest0 + + def fu_same?(a, b) #:nodoc: + File.identical?(a, b) + end + private_module_function :fu_same? + + def fu_output_message(msg) #:nodoc: + output = @fileutils_output if defined?(@fileutils_output) + output ||= $stderr + if defined?(@fileutils_label) + msg = @fileutils_label + msg + end + output.puts msg + end + private_module_function :fu_output_message + + # This hash table holds command options. + OPT_TABLE = {} #:nodoc: internal use only + (private_instance_methods & methods(false)).inject(OPT_TABLE) {|tbl, name| + (tbl[name.to_s] = instance_method(name).parameters).map! {|t, n| n if t == :key}.compact! + tbl + } + + public + + # + # Returns an Array of names of high-level methods that accept any keyword + # arguments. + # + # p Bundler::FileUtils.commands #=> ["chmod", "cp", "cp_r", "install", ...] + # + def self.commands + OPT_TABLE.keys + end + + # + # Returns an Array of option names. + # + # p Bundler::FileUtils.options #=> ["noop", "force", "verbose", "preserve", "mode"] + # + def self.options + OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s } + end + + # + # Returns true if the method +mid+ have an option +opt+. + # + # p Bundler::FileUtils.have_option?(:cp, :noop) #=> true + # p Bundler::FileUtils.have_option?(:rm, :force) #=> true + # p Bundler::FileUtils.have_option?(:rm, :preserve) #=> false + # + def self.have_option?(mid, opt) + li = OPT_TABLE[mid.to_s] or raise ArgumentError, "no such method: #{mid}" + li.include?(opt) + end + + # + # Returns an Array of option names of the method +mid+. + # + # p Bundler::FileUtils.options_of(:rm) #=> ["noop", "verbose", "force"] + # + def self.options_of(mid) + OPT_TABLE[mid.to_s].map {|sym| sym.to_s } + end + + # + # Returns an Array of methods names which have the option +opt+. + # + # p Bundler::FileUtils.collect_method(:preserve) #=> ["cp", "cp_r", "copy", "install"] + # + def self.collect_method(opt) + OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) } + end + + private + + LOW_METHODS = singleton_methods(false) - collect_method(:noop).map(&:intern) # :nodoc: + module LowMethods # :nodoc: internal use only + private + def _do_nothing(*)end + ::Bundler::FileUtils::LOW_METHODS.map {|name| alias_method name, :_do_nothing} + end + + METHODS = singleton_methods() - [:private_module_function, # :nodoc: + :commands, :options, :have_option?, :options_of, :collect_method] + + # + # This module has all methods of Bundler::FileUtils module, but it outputs messages + # before acting. This equates to passing the :verbose flag to + # methods in Bundler::FileUtils. + # + module Verbose + include Bundler::FileUtils + names = ::Bundler::FileUtils.collect_method(:verbose) + names.each do |name| + module_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{name}(*args, **options) + super(*args, **options, verbose: true) + end + EOS + end + private(*names) + extend self + class << self + public(*::Bundler::FileUtils::METHODS) + end + end + + # + # This module has all methods of Bundler::FileUtils module, but never changes + # files/directories. This equates to passing the :noop flag + # to methods in Bundler::FileUtils. + # + module NoWrite + include Bundler::FileUtils + include LowMethods + names = ::Bundler::FileUtils.collect_method(:noop) + names.each do |name| + module_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{name}(*args, **options) + super(*args, **options, noop: true) + end + EOS + end + private(*names) + extend self + class << self + public(*::Bundler::FileUtils::METHODS) + end + end + + # + # This module has all methods of Bundler::FileUtils module, but never changes + # files/directories, with printing message before acting. + # This equates to passing the :noop and :verbose flag + # to methods in Bundler::FileUtils. + # + module DryRun + include Bundler::FileUtils + include LowMethods + names = ::Bundler::FileUtils.collect_method(:noop) + names.each do |name| + module_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{name}(*args, **options) + super(*args, **options, noop: true, verbose: true) + end + EOS + end + private(*names) + extend self + class << self + public(*::Bundler::FileUtils::METHODS) + end + end + +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo.rb new file mode 100644 index 0000000..a52b96d --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require_relative 'molinillo/gem_metadata' +require_relative 'molinillo/errors' +require_relative 'molinillo/resolver' +require_relative 'molinillo/modules/ui' +require_relative 'molinillo/modules/specification_provider' + +# Bundler::Molinillo is a generic dependency resolution algorithm. +module Bundler::Molinillo +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb new file mode 100644 index 0000000..bcacf35 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module Bundler::Molinillo + # @!visibility private + module Delegates + # Delegates all {Bundler::Molinillo::ResolutionState} methods to a `#state` property. + module ResolutionState + # (see Bundler::Molinillo::ResolutionState#name) + def name + current_state = state || Bundler::Molinillo::ResolutionState.empty + current_state.name + end + + # (see Bundler::Molinillo::ResolutionState#requirements) + def requirements + current_state = state || Bundler::Molinillo::ResolutionState.empty + current_state.requirements + end + + # (see Bundler::Molinillo::ResolutionState#activated) + def activated + current_state = state || Bundler::Molinillo::ResolutionState.empty + current_state.activated + end + + # (see Bundler::Molinillo::ResolutionState#requirement) + def requirement + current_state = state || Bundler::Molinillo::ResolutionState.empty + current_state.requirement + end + + # (see Bundler::Molinillo::ResolutionState#possibilities) + def possibilities + current_state = state || Bundler::Molinillo::ResolutionState.empty + current_state.possibilities + end + + # (see Bundler::Molinillo::ResolutionState#depth) + def depth + current_state = state || Bundler::Molinillo::ResolutionState.empty + current_state.depth + end + + # (see Bundler::Molinillo::ResolutionState#conflicts) + def conflicts + current_state = state || Bundler::Molinillo::ResolutionState.empty + current_state.conflicts + end + + # (see Bundler::Molinillo::ResolutionState#unused_unwind_options) + def unused_unwind_options + current_state = state || Bundler::Molinillo::ResolutionState.empty + current_state.unused_unwind_options + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb new file mode 100644 index 0000000..f8c695c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module Bundler::Molinillo + module Delegates + # Delegates all {Bundler::Molinillo::SpecificationProvider} methods to a + # `#specification_provider` property. + module SpecificationProvider + # (see Bundler::Molinillo::SpecificationProvider#search_for) + def search_for(dependency) + with_no_such_dependency_error_handling do + specification_provider.search_for(dependency) + end + end + + # (see Bundler::Molinillo::SpecificationProvider#dependencies_for) + def dependencies_for(specification) + with_no_such_dependency_error_handling do + specification_provider.dependencies_for(specification) + end + end + + # (see Bundler::Molinillo::SpecificationProvider#requirement_satisfied_by?) + def requirement_satisfied_by?(requirement, activated, spec) + with_no_such_dependency_error_handling do + specification_provider.requirement_satisfied_by?(requirement, activated, spec) + end + end + + # (see Bundler::Molinillo::SpecificationProvider#dependencies_equal?) + def dependencies_equal?(dependencies, other_dependencies) + with_no_such_dependency_error_handling do + specification_provider.dependencies_equal?(dependencies, other_dependencies) + end + end + + # (see Bundler::Molinillo::SpecificationProvider#name_for) + def name_for(dependency) + with_no_such_dependency_error_handling do + specification_provider.name_for(dependency) + end + end + + # (see Bundler::Molinillo::SpecificationProvider#name_for_explicit_dependency_source) + def name_for_explicit_dependency_source + with_no_such_dependency_error_handling do + specification_provider.name_for_explicit_dependency_source + end + end + + # (see Bundler::Molinillo::SpecificationProvider#name_for_locking_dependency_source) + def name_for_locking_dependency_source + with_no_such_dependency_error_handling do + specification_provider.name_for_locking_dependency_source + end + end + + # (see Bundler::Molinillo::SpecificationProvider#sort_dependencies) + def sort_dependencies(dependencies, activated, conflicts) + with_no_such_dependency_error_handling do + specification_provider.sort_dependencies(dependencies, activated, conflicts) + end + end + + # (see Bundler::Molinillo::SpecificationProvider#allow_missing?) + def allow_missing?(dependency) + with_no_such_dependency_error_handling do + specification_provider.allow_missing?(dependency) + end + end + + private + + # Ensures any raised {NoSuchDependencyError} has its + # {NoSuchDependencyError#required_by} set. + # @yield + def with_no_such_dependency_error_handling + yield + rescue NoSuchDependencyError => error + if state + vertex = activated.vertex_named(name_for(error.dependency)) + error.required_by += vertex.incoming_edges.map { |e| e.origin.name } + error.required_by << name_for_explicit_dependency_source unless vertex.explicit_requirements.empty? + end + raise + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb new file mode 100644 index 0000000..4d57721 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb @@ -0,0 +1,255 @@ +# frozen_string_literal: true + +require_relative '../../../../vendored_tsort' + +require_relative 'dependency_graph/log' +require_relative 'dependency_graph/vertex' + +module Bundler::Molinillo + # A directed acyclic graph that is tuned to hold named dependencies + class DependencyGraph + include Enumerable + + # Enumerates through the vertices of the graph. + # @return [Array] The graph's vertices. + def each + return vertices.values.each unless block_given? + vertices.values.each { |v| yield v } + end + + include Bundler::TSort + + # @!visibility private + alias tsort_each_node each + + # @!visibility private + def tsort_each_child(vertex, &block) + vertex.successors.each(&block) + end + + # Topologically sorts the given vertices. + # @param [Enumerable] vertices the vertices to be sorted, which must + # all belong to the same graph. + # @return [Array] The sorted vertices. + def self.tsort(vertices) + Bundler::TSort.tsort( + lambda { |b| vertices.each(&b) }, + lambda { |v, &b| (v.successors & vertices).each(&b) } + ) + end + + # A directed edge of a {DependencyGraph} + # @attr [Vertex] origin The origin of the directed edge + # @attr [Vertex] destination The destination of the directed edge + # @attr [Object] requirement The requirement the directed edge represents + Edge = Struct.new(:origin, :destination, :requirement) + + # @return [{String => Vertex}] the vertices of the dependency graph, keyed + # by {Vertex#name} + attr_reader :vertices + + # @return [Log] the op log for this graph + attr_reader :log + + # Initializes an empty dependency graph + def initialize + @vertices = {} + @log = Log.new + end + + # Tags the current state of the dependency as the given tag + # @param [Object] tag an opaque tag for the current state of the graph + # @return [Void] + def tag(tag) + log.tag(self, tag) + end + + # Rewinds the graph to the state tagged as `tag` + # @param [Object] tag the tag to rewind to + # @return [Void] + def rewind_to(tag) + log.rewind_to(self, tag) + end + + # Initializes a copy of a {DependencyGraph}, ensuring that all {#vertices} + # are properly copied. + # @param [DependencyGraph] other the graph to copy. + def initialize_copy(other) + super + @vertices = {} + @log = other.log.dup + traverse = lambda do |new_v, old_v| + return if new_v.outgoing_edges.size == old_v.outgoing_edges.size + old_v.outgoing_edges.each do |edge| + destination = add_vertex(edge.destination.name, edge.destination.payload) + add_edge_no_circular(new_v, destination, edge.requirement) + traverse.call(destination, edge.destination) + end + end + other.vertices.each do |name, vertex| + new_vertex = add_vertex(name, vertex.payload, vertex.root?) + new_vertex.explicit_requirements.replace(vertex.explicit_requirements) + traverse.call(new_vertex, vertex) + end + end + + # @return [String] a string suitable for debugging + def inspect + "#{self.class}:#{vertices.values.inspect}" + end + + # @param [Hash] options options for dot output. + # @return [String] Returns a dot format representation of the graph + def to_dot(options = {}) + edge_label = options.delete(:edge_label) + raise ArgumentError, "Unknown options: #{options.keys}" unless options.empty? + + dot_vertices = [] + dot_edges = [] + vertices.each do |n, v| + dot_vertices << " #{n} [label=\"{#{n}|#{v.payload}}\"]" + v.outgoing_edges.each do |e| + label = edge_label ? edge_label.call(e) : e.requirement + dot_edges << " #{e.origin.name} -> #{e.destination.name} [label=#{label.to_s.dump}]" + end + end + + dot_vertices.uniq! + dot_vertices.sort! + dot_edges.uniq! + dot_edges.sort! + + dot = dot_vertices.unshift('digraph G {').push('') + dot_edges.push('}') + dot.join("\n") + end + + # @param [DependencyGraph] other + # @return [Boolean] whether the two dependency graphs are equal, determined + # by a recursive traversal of each {#root_vertices} and its + # {Vertex#successors} + def ==(other) + return false unless other + return true if equal?(other) + vertices.each do |name, vertex| + other_vertex = other.vertex_named(name) + return false unless other_vertex + return false unless vertex.payload == other_vertex.payload + return false unless other_vertex.successors.to_set == vertex.successors.to_set + end + end + + # @param [String] name + # @param [Object] payload + # @param [Array] parent_names + # @param [Object] requirement the requirement that is requiring the child + # @return [void] + def add_child_vertex(name, payload, parent_names, requirement) + root = !parent_names.delete(nil) { true } + vertex = add_vertex(name, payload, root) + vertex.explicit_requirements << requirement if root + parent_names.each do |parent_name| + parent_vertex = vertex_named(parent_name) + add_edge(parent_vertex, vertex, requirement) + end + vertex + end + + # Adds a vertex with the given name, or updates the existing one. + # @param [String] name + # @param [Object] payload + # @return [Vertex] the vertex that was added to `self` + def add_vertex(name, payload, root = false) + log.add_vertex(self, name, payload, root) + end + + # Detaches the {#vertex_named} `name` {Vertex} from the graph, recursively + # removing any non-root vertices that were orphaned in the process + # @param [String] name + # @return [Array] the vertices which have been detached + def detach_vertex_named(name) + log.detach_vertex_named(self, name) + end + + # @param [String] name + # @return [Vertex,nil] the vertex with the given name + def vertex_named(name) + vertices[name] + end + + # @param [String] name + # @return [Vertex,nil] the root vertex with the given name + def root_vertex_named(name) + vertex = vertex_named(name) + vertex if vertex && vertex.root? + end + + # Adds a new {Edge} to the dependency graph + # @param [Vertex] origin + # @param [Vertex] destination + # @param [Object] requirement the requirement that this edge represents + # @return [Edge] the added edge + def add_edge(origin, destination, requirement) + if destination.path_to?(origin) + raise CircularDependencyError.new(path(destination, origin)) + end + add_edge_no_circular(origin, destination, requirement) + end + + # Deletes an {Edge} from the dependency graph + # @param [Edge] edge + # @return [Void] + def delete_edge(edge) + log.delete_edge(self, edge.origin.name, edge.destination.name, edge.requirement) + end + + # Sets the payload of the vertex with the given name + # @param [String] name the name of the vertex + # @param [Object] payload the payload + # @return [Void] + def set_payload(name, payload) + log.set_payload(self, name, payload) + end + + private + + # Adds a new {Edge} to the dependency graph without checking for + # circularity. + # @param (see #add_edge) + # @return (see #add_edge) + def add_edge_no_circular(origin, destination, requirement) + log.add_edge_no_circular(self, origin.name, destination.name, requirement) + end + + # Returns the path between two vertices + # @raise [ArgumentError] if there is no path between the vertices + # @param [Vertex] from + # @param [Vertex] to + # @return [Array] the shortest path from `from` to `to` + def path(from, to) + distances = Hash.new(vertices.size + 1) + distances[from.name] = 0 + predecessors = {} + each do |vertex| + vertex.successors.each do |successor| + if distances[successor.name] > distances[vertex.name] + 1 + distances[successor.name] = distances[vertex.name] + 1 + predecessors[successor] = vertex + end + end + end + + path = [to] + while before = predecessors[to] + path << before + to = before + break if to == from + end + + unless path.last.equal?(from) + raise ArgumentError, "There is no path from #{from.name} to #{to.name}" + end + + path.reverse + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb new file mode 100644 index 0000000..c04c7ee --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Bundler::Molinillo + class DependencyGraph + # An action that modifies a {DependencyGraph} that is reversible. + # @abstract + class Action + # rubocop:disable Lint/UnusedMethodArgument + + # @return [Symbol] The name of the action. + def self.action_name + raise 'Abstract' + end + + # Performs the action on the given graph. + # @param [DependencyGraph] graph the graph to perform the action on. + # @return [Void] + def up(graph) + raise 'Abstract' + end + + # Reverses the action on the given graph. + # @param [DependencyGraph] graph the graph to reverse the action on. + # @return [Void] + def down(graph) + raise 'Abstract' + end + + # @return [Action,Nil] The previous action + attr_accessor :previous + + # @return [Action,Nil] The next action + attr_accessor :next + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb new file mode 100644 index 0000000..946a082 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +require_relative 'action' +module Bundler::Molinillo + class DependencyGraph + # @!visibility private + # (see DependencyGraph#add_edge_no_circular) + class AddEdgeNoCircular < Action + # @!group Action + + # (see Action.action_name) + def self.action_name + :add_vertex + end + + # (see Action#up) + def up(graph) + edge = make_edge(graph) + edge.origin.outgoing_edges << edge + edge.destination.incoming_edges << edge + edge + end + + # (see Action#down) + def down(graph) + edge = make_edge(graph) + delete_first(edge.origin.outgoing_edges, edge) + delete_first(edge.destination.incoming_edges, edge) + end + + # @!group AddEdgeNoCircular + + # @return [String] the name of the origin of the edge + attr_reader :origin + + # @return [String] the name of the destination of the edge + attr_reader :destination + + # @return [Object] the requirement that the edge represents + attr_reader :requirement + + # @param [DependencyGraph] graph the graph to find vertices from + # @return [Edge] The edge this action adds + def make_edge(graph) + Edge.new(graph.vertex_named(origin), graph.vertex_named(destination), requirement) + end + + # Initialize an action to add an edge to a dependency graph + # @param [String] origin the name of the origin of the edge + # @param [String] destination the name of the destination of the edge + # @param [Object] requirement the requirement that the edge represents + def initialize(origin, destination, requirement) + @origin = origin + @destination = destination + @requirement = requirement + end + + private + + def delete_first(array, item) + return unless index = array.index(item) + array.delete_at(index) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb new file mode 100644 index 0000000..483527d --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require_relative 'action' +module Bundler::Molinillo + class DependencyGraph + # @!visibility private + # (see DependencyGraph#add_vertex) + class AddVertex < Action # :nodoc: + # @!group Action + + # (see Action.action_name) + def self.action_name + :add_vertex + end + + # (see Action#up) + def up(graph) + if existing = graph.vertices[name] + @existing_payload = existing.payload + @existing_root = existing.root + end + vertex = existing || Vertex.new(name, payload) + graph.vertices[vertex.name] = vertex + vertex.payload ||= payload + vertex.root ||= root + vertex + end + + # (see Action#down) + def down(graph) + if defined?(@existing_payload) + vertex = graph.vertices[name] + vertex.payload = @existing_payload + vertex.root = @existing_root + else + graph.vertices.delete(name) + end + end + + # @!group AddVertex + + # @return [String] the name of the vertex + attr_reader :name + + # @return [Object] the payload for the vertex + attr_reader :payload + + # @return [Boolean] whether the vertex is root or not + attr_reader :root + + # Initialize an action to add a vertex to a dependency graph + # @param [String] name the name of the vertex + # @param [Object] payload the payload for the vertex + # @param [Boolean] root whether the vertex is root or not + def initialize(name, payload, root) + @name = name + @payload = payload + @root = root + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb new file mode 100644 index 0000000..d819405 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require_relative 'action' +module Bundler::Molinillo + class DependencyGraph + # @!visibility private + # (see DependencyGraph#delete_edge) + class DeleteEdge < Action + # @!group Action + + # (see Action.action_name) + def self.action_name + :delete_edge + end + + # (see Action#up) + def up(graph) + edge = make_edge(graph) + edge.origin.outgoing_edges.delete(edge) + edge.destination.incoming_edges.delete(edge) + end + + # (see Action#down) + def down(graph) + edge = make_edge(graph) + edge.origin.outgoing_edges << edge + edge.destination.incoming_edges << edge + edge + end + + # @!group DeleteEdge + + # @return [String] the name of the origin of the edge + attr_reader :origin_name + + # @return [String] the name of the destination of the edge + attr_reader :destination_name + + # @return [Object] the requirement that the edge represents + attr_reader :requirement + + # @param [DependencyGraph] graph the graph to find vertices from + # @return [Edge] The edge this action adds + def make_edge(graph) + Edge.new( + graph.vertex_named(origin_name), + graph.vertex_named(destination_name), + requirement + ) + end + + # Initialize an action to add an edge to a dependency graph + # @param [String] origin_name the name of the origin of the edge + # @param [String] destination_name the name of the destination of the edge + # @param [Object] requirement the requirement that the edge represents + def initialize(origin_name, destination_name, requirement) + @origin_name = origin_name + @destination_name = destination_name + @requirement = requirement + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb new file mode 100644 index 0000000..36fce7c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require_relative 'action' +module Bundler::Molinillo + class DependencyGraph + # @!visibility private + # @see DependencyGraph#detach_vertex_named + class DetachVertexNamed < Action + # @!group Action + + # (see Action#name) + def self.action_name + :add_vertex + end + + # (see Action#up) + def up(graph) + return [] unless @vertex = graph.vertices.delete(name) + + removed_vertices = [@vertex] + @vertex.outgoing_edges.each do |e| + v = e.destination + v.incoming_edges.delete(e) + if !v.root? && v.incoming_edges.empty? + removed_vertices.concat graph.detach_vertex_named(v.name) + end + end + + @vertex.incoming_edges.each do |e| + v = e.origin + v.outgoing_edges.delete(e) + end + + removed_vertices + end + + # (see Action#down) + def down(graph) + return unless @vertex + graph.vertices[@vertex.name] = @vertex + @vertex.outgoing_edges.each do |e| + e.destination.incoming_edges << e + end + @vertex.incoming_edges.each do |e| + e.origin.outgoing_edges << e + end + end + + # @!group DetachVertexNamed + + # @return [String] the name of the vertex to detach + attr_reader :name + + # Initialize an action to detach a vertex from a dependency graph + # @param [String] name the name of the vertex to detach + def initialize(name) + @name = name + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb new file mode 100644 index 0000000..6f0de19 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb @@ -0,0 +1,126 @@ +# frozen_string_literal: true + +require_relative 'add_edge_no_circular' +require_relative 'add_vertex' +require_relative 'delete_edge' +require_relative 'detach_vertex_named' +require_relative 'set_payload' +require_relative 'tag' + +module Bundler::Molinillo + class DependencyGraph + # A log for dependency graph actions + class Log + # Initializes an empty log + def initialize + @current_action = @first_action = nil + end + + # @!macro [new] action + # {include:DependencyGraph#$0} + # @param [Graph] graph the graph to perform the action on + # @param (see DependencyGraph#$0) + # @return (see DependencyGraph#$0) + + # @macro action + def tag(graph, tag) + push_action(graph, Tag.new(tag)) + end + + # @macro action + def add_vertex(graph, name, payload, root) + push_action(graph, AddVertex.new(name, payload, root)) + end + + # @macro action + def detach_vertex_named(graph, name) + push_action(graph, DetachVertexNamed.new(name)) + end + + # @macro action + def add_edge_no_circular(graph, origin, destination, requirement) + push_action(graph, AddEdgeNoCircular.new(origin, destination, requirement)) + end + + # {include:DependencyGraph#delete_edge} + # @param [Graph] graph the graph to perform the action on + # @param [String] origin_name + # @param [String] destination_name + # @param [Object] requirement + # @return (see DependencyGraph#delete_edge) + def delete_edge(graph, origin_name, destination_name, requirement) + push_action(graph, DeleteEdge.new(origin_name, destination_name, requirement)) + end + + # @macro action + def set_payload(graph, name, payload) + push_action(graph, SetPayload.new(name, payload)) + end + + # Pops the most recent action from the log and undoes the action + # @param [DependencyGraph] graph + # @return [Action] the action that was popped off the log + def pop!(graph) + return unless action = @current_action + unless @current_action = action.previous + @first_action = nil + end + action.down(graph) + action + end + + extend Enumerable + + # @!visibility private + # Enumerates each action in the log + # @yield [Action] + def each + return enum_for unless block_given? + action = @first_action + loop do + break unless action + yield action + action = action.next + end + self + end + + # @!visibility private + # Enumerates each action in the log in reverse order + # @yield [Action] + def reverse_each + return enum_for(:reverse_each) unless block_given? + action = @current_action + loop do + break unless action + yield action + action = action.previous + end + self + end + + # @macro action + def rewind_to(graph, tag) + loop do + action = pop!(graph) + raise "No tag #{tag.inspect} found" unless action + break if action.class.action_name == :tag && action.tag == tag + end + end + + private + + # Adds the given action to the log, running the action + # @param [DependencyGraph] graph + # @param [Action] action + # @return The value returned by `action.up` + def push_action(graph, action) + action.previous = @current_action + @current_action.next = action if @current_action + @current_action = action + @first_action ||= action + action.up(graph) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb new file mode 100644 index 0000000..2e9b90e --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require_relative 'action' +module Bundler::Molinillo + class DependencyGraph + # @!visibility private + # @see DependencyGraph#set_payload + class SetPayload < Action # :nodoc: + # @!group Action + + # (see Action.action_name) + def self.action_name + :set_payload + end + + # (see Action#up) + def up(graph) + vertex = graph.vertex_named(name) + @old_payload = vertex.payload + vertex.payload = payload + end + + # (see Action#down) + def down(graph) + graph.vertex_named(name).payload = @old_payload + end + + # @!group SetPayload + + # @return [String] the name of the vertex + attr_reader :name + + # @return [Object] the payload for the vertex + attr_reader :payload + + # Initialize an action to add set the payload for a vertex in a dependency + # graph + # @param [String] name the name of the vertex + # @param [Object] payload the payload for the vertex + def initialize(name, payload) + @name = name + @payload = payload + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb new file mode 100644 index 0000000..5b5da3e --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require_relative 'action' +module Bundler::Molinillo + class DependencyGraph + # @!visibility private + # @see DependencyGraph#tag + class Tag < Action + # @!group Action + + # (see Action.action_name) + def self.action_name + :tag + end + + # (see Action#up) + def up(graph) + end + + # (see Action#down) + def down(graph) + end + + # @!group Tag + + # @return [Object] An opaque tag + attr_reader :tag + + # Initialize an action to tag a state of a dependency graph + # @param [Object] tag an opaque tag + def initialize(tag) + @tag = tag + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb new file mode 100644 index 0000000..1185a8a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb @@ -0,0 +1,164 @@ +# frozen_string_literal: true + +module Bundler::Molinillo + class DependencyGraph + # A vertex in a {DependencyGraph} that encapsulates a {#name} and a + # {#payload} + class Vertex + # @return [String] the name of the vertex + attr_accessor :name + + # @return [Object] the payload the vertex holds + attr_accessor :payload + + # @return [Array] the explicit requirements that required + # this vertex + attr_reader :explicit_requirements + + # @return [Boolean] whether the vertex is considered a root vertex + attr_accessor :root + alias root? root + + # Initializes a vertex with the given name and payload. + # @param [String] name see {#name} + # @param [Object] payload see {#payload} + def initialize(name, payload) + @name = name.frozen? ? name : name.dup.freeze + @payload = payload + @explicit_requirements = [] + @outgoing_edges = [] + @incoming_edges = [] + end + + # @return [Array] all of the requirements that required + # this vertex + def requirements + (incoming_edges.map(&:requirement) + explicit_requirements).uniq + end + + # @return [Array] the edges of {#graph} that have `self` as their + # {Edge#origin} + attr_accessor :outgoing_edges + + # @return [Array] the edges of {#graph} that have `self` as their + # {Edge#destination} + attr_accessor :incoming_edges + + # @return [Array] the vertices of {#graph} that have an edge with + # `self` as their {Edge#destination} + def predecessors + incoming_edges.map(&:origin) + end + + # @return [Set] the vertices of {#graph} where `self` is a + # {#descendent?} + def recursive_predecessors + _recursive_predecessors + end + + # @param [Set] vertices the set to add the predecessors to + # @return [Set] the vertices of {#graph} where `self` is a + # {#descendent?} + def _recursive_predecessors(vertices = new_vertex_set) + incoming_edges.each do |edge| + vertex = edge.origin + next unless vertices.add?(vertex) + vertex._recursive_predecessors(vertices) + end + + vertices + end + protected :_recursive_predecessors + + # @return [Array] the vertices of {#graph} that have an edge with + # `self` as their {Edge#origin} + def successors + outgoing_edges.map(&:destination) + end + + # @return [Set] the vertices of {#graph} where `self` is an + # {#ancestor?} + def recursive_successors + _recursive_successors + end + + # @param [Set] vertices the set to add the successors to + # @return [Set] the vertices of {#graph} where `self` is an + # {#ancestor?} + def _recursive_successors(vertices = new_vertex_set) + outgoing_edges.each do |edge| + vertex = edge.destination + next unless vertices.add?(vertex) + vertex._recursive_successors(vertices) + end + + vertices + end + protected :_recursive_successors + + # @return [String] a string suitable for debugging + def inspect + "#{self.class}:#{name}(#{payload.inspect})" + end + + # @return [Boolean] whether the two vertices are equal, determined + # by a recursive traversal of each {Vertex#successors} + def ==(other) + return true if equal?(other) + shallow_eql?(other) && + successors.to_set == other.successors.to_set + end + + # @param [Vertex] other the other vertex to compare to + # @return [Boolean] whether the two vertices are equal, determined + # solely by {#name} and {#payload} equality + def shallow_eql?(other) + return true if equal?(other) + other && + name == other.name && + payload == other.payload + end + + alias eql? == + + # @return [Fixnum] a hash for the vertex based upon its {#name} + def hash + name.hash + end + + # Is there a path from `self` to `other` following edges in the + # dependency graph? + # @return whether there is a path following edges within this {#graph} + def path_to?(other) + _path_to?(other) + end + + alias descendent? path_to? + + # @param [Vertex] other the vertex to check if there's a path to + # @param [Set] visited the vertices of {#graph} that have been visited + # @return [Boolean] whether there is a path to `other` from `self` + def _path_to?(other, visited = new_vertex_set) + return false unless visited.add?(self) + return true if equal?(other) + successors.any? { |v| v._path_to?(other, visited) } + end + protected :_path_to? + + # Is there a path from `other` to `self` following edges in the + # dependency graph? + # @return whether there is a path following edges within this {#graph} + def ancestor?(other) + other.path_to?(self) + end + + alias is_reachable_from? ancestor? + + def new_vertex_set + require 'set' + Set.new + end + private :new_vertex_set + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/errors.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/errors.rb new file mode 100644 index 0000000..8c8cafb --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/errors.rb @@ -0,0 +1,149 @@ +# frozen_string_literal: true + +module Bundler::Molinillo + # An error that occurred during the resolution process + class ResolverError < StandardError; end + + # An error caused by searching for a dependency that is completely unknown, + # i.e. has no versions available whatsoever. + class NoSuchDependencyError < ResolverError + # @return [Object] the dependency that could not be found + attr_accessor :dependency + + # @return [Array] the specifications that depended upon {#dependency} + attr_accessor :required_by + + # Initializes a new error with the given missing dependency. + # @param [Object] dependency @see {#dependency} + # @param [Array] required_by @see {#required_by} + def initialize(dependency, required_by = []) + @dependency = dependency + @required_by = required_by.uniq + super() + end + + # The error message for the missing dependency, including the specifications + # that had this dependency. + def message + sources = required_by.map { |r| "`#{r}`" }.join(' and ') + message = "Unable to find a specification for `#{dependency}`" + message += " depended upon by #{sources}" unless sources.empty? + message + end + end + + # An error caused by attempting to fulfil a dependency that was circular + # + # @note This exception will be thrown if and only if a {Vertex} is added to a + # {DependencyGraph} that has a {DependencyGraph::Vertex#path_to?} an + # existing {DependencyGraph::Vertex} + class CircularDependencyError < ResolverError + # [Set] the dependencies responsible for causing the error + attr_reader :dependencies + + # Initializes a new error with the given circular vertices. + # @param [Array] vertices the vertices in the dependency + # that caused the error + def initialize(vertices) + super "There is a circular dependency between #{vertices.map(&:name).join(' and ')}" + @dependencies = vertices.map { |vertex| vertex.payload.possibilities.last }.to_set + end + end + + # An error caused by conflicts in version + class VersionConflict < ResolverError + # @return [{String => Resolution::Conflict}] the conflicts that caused + # resolution to fail + attr_reader :conflicts + + # @return [SpecificationProvider] the specification provider used during + # resolution + attr_reader :specification_provider + + # Initializes a new error with the given version conflicts. + # @param [{String => Resolution::Conflict}] conflicts see {#conflicts} + # @param [SpecificationProvider] specification_provider see {#specification_provider} + def initialize(conflicts, specification_provider) + pairs = [] + conflicts.values.flat_map(&:requirements).each do |conflicting| + conflicting.each do |source, conflict_requirements| + conflict_requirements.each do |c| + pairs << [c, source] + end + end + end + + super "Unable to satisfy the following requirements:\n\n" \ + "#{pairs.map { |r, d| "- `#{r}` required by `#{d}`" }.join("\n")}" + + @conflicts = conflicts + @specification_provider = specification_provider + end + + require_relative 'delegates/specification_provider' + include Delegates::SpecificationProvider + + # @return [String] An error message that includes requirement trees, + # which is much more detailed & customizable than the default message + # @param [Hash] opts the options to create a message with. + # @option opts [String] :solver_name The user-facing name of the solver + # @option opts [String] :possibility_type The generic name of a possibility + # @option opts [Proc] :reduce_trees A proc that reduced the list of requirement trees + # @option opts [Proc] :printable_requirement A proc that pretty-prints requirements + # @option opts [Proc] :additional_message_for_conflict A proc that appends additional + # messages for each conflict + # @option opts [Proc] :version_for_spec A proc that returns the version number for a + # possibility + def message_with_trees(opts = {}) + solver_name = opts.delete(:solver_name) { self.class.name.split('::').first } + possibility_type = opts.delete(:possibility_type) { 'possibility named' } + reduce_trees = opts.delete(:reduce_trees) { proc { |trees| trees.uniq.sort_by(&:to_s) } } + printable_requirement = opts.delete(:printable_requirement) { proc { |req| req.to_s } } + additional_message_for_conflict = opts.delete(:additional_message_for_conflict) { proc {} } + version_for_spec = opts.delete(:version_for_spec) { proc(&:to_s) } + incompatible_version_message_for_conflict = opts.delete(:incompatible_version_message_for_conflict) do + proc do |name, _conflict| + %(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":) + end + end + + full_message_for_conflict = opts.delete(:full_message_for_conflict) do + proc do |name, conflict| + o = "\n".dup << incompatible_version_message_for_conflict.call(name, conflict) << "\n" + if conflict.locked_requirement + o << %( In snapshot (#{name_for_locking_dependency_source}):\n) + o << %( #{printable_requirement.call(conflict.locked_requirement)}\n) + o << %(\n) + end + o << %( In #{name_for_explicit_dependency_source}:\n) + trees = reduce_trees.call(conflict.requirement_trees) + + o << trees.map do |tree| + t = ''.dup + depth = 2 + tree.each do |req| + t << ' ' * depth << printable_requirement.call(req) + unless tree.last == req + if spec = conflict.activated_by_name[name_for(req)] + t << %( was resolved to #{version_for_spec.call(spec)}, which) + end + t << %( depends on) + end + t << %(\n) + depth += 1 + end + t + end.join("\n") + + additional_message_for_conflict.call(o, name, conflict) + + o + end + end + + conflicts.sort.reduce(''.dup) do |o, (name, conflict)| + o << full_message_for_conflict.call(name, conflict) + end.strip + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb new file mode 100644 index 0000000..a0cfc21 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +module Bundler::Molinillo + # The version of Bundler::Molinillo. + VERSION = '0.8.0'.freeze +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb new file mode 100644 index 0000000..eeae79a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true + +module Bundler::Molinillo + # Provides information about specifications and dependencies to the resolver, + # allowing the {Resolver} class to remain generic while still providing power + # and flexibility. + # + # This module contains the methods that users of Bundler::Molinillo must to implement, + # using knowledge of their own model classes. + module SpecificationProvider + # Search for the specifications that match the given dependency. + # The specifications in the returned array will be considered in reverse + # order, so the latest version ought to be last. + # @note This method should be 'pure', i.e. the return value should depend + # only on the `dependency` parameter. + # + # @param [Object] dependency + # @return [Array] the specifications that satisfy the given + # `dependency`. + def search_for(dependency) + [] + end + + # Returns the dependencies of `specification`. + # @note This method should be 'pure', i.e. the return value should depend + # only on the `specification` parameter. + # + # @param [Object] specification + # @return [Array] the dependencies that are required by the given + # `specification`. + def dependencies_for(specification) + [] + end + + # Determines whether the given `requirement` is satisfied by the given + # `spec`, in the context of the current `activated` dependency graph. + # + # @param [Object] requirement + # @param [DependencyGraph] activated the current dependency graph in the + # resolution process. + # @param [Object] spec + # @return [Boolean] whether `requirement` is satisfied by `spec` in the + # context of the current `activated` dependency graph. + def requirement_satisfied_by?(requirement, activated, spec) + true + end + + # Determines whether two arrays of dependencies are equal, and thus can be + # grouped. + # + # @param [Array] dependencies + # @param [Array] other_dependencies + # @return [Boolean] whether `dependencies` and `other_dependencies` should + # be considered equal. + def dependencies_equal?(dependencies, other_dependencies) + dependencies == other_dependencies + end + + # Returns the name for the given `dependency`. + # @note This method should be 'pure', i.e. the return value should depend + # only on the `dependency` parameter. + # + # @param [Object] dependency + # @return [String] the name for the given `dependency`. + def name_for(dependency) + dependency.to_s + end + + # @return [String] the name of the source of explicit dependencies, i.e. + # those passed to {Resolver#resolve} directly. + def name_for_explicit_dependency_source + 'user-specified dependency' + end + + # @return [String] the name of the source of 'locked' dependencies, i.e. + # those passed to {Resolver#resolve} directly as the `base` + def name_for_locking_dependency_source + 'Lockfile' + end + + # Sort dependencies so that the ones that are easiest to resolve are first. + # Easiest to resolve is (usually) defined by: + # 1) Is this dependency already activated? + # 2) How relaxed are the requirements? + # 3) Are there any conflicts for this dependency? + # 4) How many possibilities are there to satisfy this dependency? + # + # @param [Array] dependencies + # @param [DependencyGraph] activated the current dependency graph in the + # resolution process. + # @param [{String => Array}] conflicts + # @return [Array] a sorted copy of `dependencies`. + def sort_dependencies(dependencies, activated, conflicts) + dependencies.sort_by do |dependency| + name = name_for(dependency) + [ + activated.vertex_named(name).payload ? 0 : 1, + conflicts[name] ? 0 : 1, + ] + end + end + + # Returns whether this dependency, which has no possible matching + # specifications, can safely be ignored. + # + # @param [Object] dependency + # @return [Boolean] whether this dependency can safely be skipped. + def allow_missing?(dependency) + false + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb new file mode 100644 index 0000000..a166bc6 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +module Bundler::Molinillo + # Conveys information about the resolution process to a user. + module UI + # The {IO} object that should be used to print output. `STDOUT`, by default. + # + # @return [IO] + def output + STDOUT + end + + # Called roughly every {#progress_rate}, this method should convey progress + # to the user. + # + # @return [void] + def indicate_progress + output.print '.' unless debug? + end + + # How often progress should be conveyed to the user via + # {#indicate_progress}, in seconds. A third of a second, by default. + # + # @return [Float] + def progress_rate + 0.33 + end + + # Called before resolution begins. + # + # @return [void] + def before_resolution + output.print 'Resolving dependencies...' + end + + # Called after resolution ends (either successfully or with an error). + # By default, prints a newline. + # + # @return [void] + def after_resolution + output.puts + end + + # Conveys debug information to the user. + # + # @param [Integer] depth the current depth of the resolution process. + # @return [void] + def debug(depth = 0) + if debug? + debug_info = yield + debug_info = debug_info.inspect unless debug_info.is_a?(String) + debug_info = debug_info.split("\n").map { |s| ":#{depth.to_s.rjust 4}: #{s}" } + output.puts debug_info + end + end + + # Whether or not debug messages should be printed. + # By default, whether or not the `MOLINILLO_DEBUG` environment variable is + # set. + # + # @return [Boolean] + def debug? + return @debug_mode if defined?(@debug_mode) + @debug_mode = ENV['MOLINILLO_DEBUG'] + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/resolution.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/resolution.rb new file mode 100644 index 0000000..c689ca7 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/resolution.rb @@ -0,0 +1,839 @@ +# frozen_string_literal: true + +module Bundler::Molinillo + class Resolver + # A specific resolution from a given {Resolver} + class Resolution + # A conflict that the resolution process encountered + # @attr [Object] requirement the requirement that immediately led to the conflict + # @attr [{String,Nil=>[Object]}] requirements the requirements that caused the conflict + # @attr [Object, nil] existing the existing spec that was in conflict with + # the {#possibility} + # @attr [Object] possibility_set the set of specs that was unable to be + # activated due to a conflict. + # @attr [Object] locked_requirement the relevant locking requirement. + # @attr [Array>] requirement_trees the different requirement + # trees that led to every requirement for the conflicting name. + # @attr [{String=>Object}] activated_by_name the already-activated specs. + # @attr [Object] underlying_error an error that has occurred during resolution, and + # will be raised at the end of it if no resolution is found. + Conflict = Struct.new( + :requirement, + :requirements, + :existing, + :possibility_set, + :locked_requirement, + :requirement_trees, + :activated_by_name, + :underlying_error + ) + + class Conflict + # @return [Object] a spec that was unable to be activated due to a conflict + def possibility + possibility_set && possibility_set.latest_version + end + end + + # A collection of possibility states that share the same dependencies + # @attr [Array] dependencies the dependencies for this set of possibilities + # @attr [Array] possibilities the possibilities + PossibilitySet = Struct.new(:dependencies, :possibilities) + + class PossibilitySet + # String representation of the possibility set, for debugging + def to_s + "[#{possibilities.join(', ')}]" + end + + # @return [Object] most up-to-date dependency in the possibility set + def latest_version + possibilities.last + end + end + + # Details of the state to unwind to when a conflict occurs, and the cause of the unwind + # @attr [Integer] state_index the index of the state to unwind to + # @attr [Object] state_requirement the requirement of the state we're unwinding to + # @attr [Array] requirement_tree for the requirement we're relaxing + # @attr [Array] conflicting_requirements the requirements that combined to cause the conflict + # @attr [Array] requirement_trees for the conflict + # @attr [Array] requirements_unwound_to_instead array of unwind requirements that were chosen over this unwind + UnwindDetails = Struct.new( + :state_index, + :state_requirement, + :requirement_tree, + :conflicting_requirements, + :requirement_trees, + :requirements_unwound_to_instead + ) + + class UnwindDetails + include Comparable + + # We compare UnwindDetails when choosing which state to unwind to. If + # two options have the same state_index we prefer the one most + # removed from a requirement that caused the conflict. Both options + # would unwind to the same state, but a `grandparent` option will + # filter out fewer of its possibilities after doing so - where a state + # is both a `parent` and a `grandparent` to requirements that have + # caused a conflict this is the correct behaviour. + # @param [UnwindDetail] other UnwindDetail to be compared + # @return [Integer] integer specifying ordering + def <=>(other) + if state_index > other.state_index + 1 + elsif state_index == other.state_index + reversed_requirement_tree_index <=> other.reversed_requirement_tree_index + else + -1 + end + end + + # @return [Integer] index of state requirement in reversed requirement tree + # (the conflicting requirement itself will be at position 0) + def reversed_requirement_tree_index + @reversed_requirement_tree_index ||= + if state_requirement + requirement_tree.reverse.index(state_requirement) + else + 999_999 + end + end + + # @return [Boolean] where the requirement of the state we're unwinding + # to directly caused the conflict. Note: in this case, it is + # impossible for the state we're unwinding to to be a parent of + # any of the other conflicting requirements (or we would have + # circularity) + def unwinding_to_primary_requirement? + requirement_tree.last == state_requirement + end + + # @return [Array] array of sub-dependencies to avoid when choosing a + # new possibility for the state we've unwound to. Only relevant for + # non-primary unwinds + def sub_dependencies_to_avoid + @requirements_to_avoid ||= + requirement_trees.map do |tree| + index = tree.index(state_requirement) + tree[index + 1] if index + end.compact + end + + # @return [Array] array of all the requirements that led to the need for + # this unwind + def all_requirements + @all_requirements ||= requirement_trees.flatten(1) + end + end + + # @return [SpecificationProvider] the provider that knows about + # dependencies, requirements, specifications, versions, etc. + attr_reader :specification_provider + + # @return [UI] the UI that knows how to communicate feedback about the + # resolution process back to the user + attr_reader :resolver_ui + + # @return [DependencyGraph] the base dependency graph to which + # dependencies should be 'locked' + attr_reader :base + + # @return [Array] the dependencies that were explicitly required + attr_reader :original_requested + + # Initializes a new resolution. + # @param [SpecificationProvider] specification_provider + # see {#specification_provider} + # @param [UI] resolver_ui see {#resolver_ui} + # @param [Array] requested see {#original_requested} + # @param [DependencyGraph] base see {#base} + def initialize(specification_provider, resolver_ui, requested, base) + @specification_provider = specification_provider + @resolver_ui = resolver_ui + @original_requested = requested + @base = base + @states = [] + @iteration_counter = 0 + @parents_of = Hash.new { |h, k| h[k] = [] } + end + + # Resolves the {#original_requested} dependencies into a full dependency + # graph + # @raise [ResolverError] if successful resolution is impossible + # @return [DependencyGraph] the dependency graph of successfully resolved + # dependencies + def resolve + start_resolution + + while state + break if !state.requirement && state.requirements.empty? + indicate_progress + if state.respond_to?(:pop_possibility_state) # DependencyState + debug(depth) { "Creating possibility state for #{requirement} (#{possibilities.count} remaining)" } + state.pop_possibility_state.tap do |s| + if s + states.push(s) + activated.tag(s) + end + end + end + process_topmost_state + end + + resolve_activated_specs + ensure + end_resolution + end + + # @return [Integer] the number of resolver iterations in between calls to + # {#resolver_ui}'s {UI#indicate_progress} method + attr_accessor :iteration_rate + private :iteration_rate + + # @return [Time] the time at which resolution began + attr_accessor :started_at + private :started_at + + # @return [Array] the stack of states for the resolution + attr_accessor :states + private :states + + private + + # Sets up the resolution process + # @return [void] + def start_resolution + @started_at = Time.now + + push_initial_state + + debug { "Starting resolution (#{@started_at})\nUser-requested dependencies: #{original_requested}" } + resolver_ui.before_resolution + end + + def resolve_activated_specs + activated.vertices.each do |_, vertex| + next unless vertex.payload + + latest_version = vertex.payload.possibilities.reverse_each.find do |possibility| + vertex.requirements.all? { |req| requirement_satisfied_by?(req, activated, possibility) } + end + + activated.set_payload(vertex.name, latest_version) + end + activated.freeze + end + + # Ends the resolution process + # @return [void] + def end_resolution + resolver_ui.after_resolution + debug do + "Finished resolution (#{@iteration_counter} steps) " \ + "(Took #{(ended_at = Time.now) - @started_at} seconds) (#{ended_at})" + end + debug { 'Unactivated: ' + Hash[activated.vertices.reject { |_n, v| v.payload }].keys.join(', ') } if state + debug { 'Activated: ' + Hash[activated.vertices.select { |_n, v| v.payload }].keys.join(', ') } if state + end + + require_relative 'state' + require_relative 'modules/specification_provider' + + require_relative 'delegates/resolution_state' + require_relative 'delegates/specification_provider' + + include Bundler::Molinillo::Delegates::ResolutionState + include Bundler::Molinillo::Delegates::SpecificationProvider + + # Processes the topmost available {RequirementState} on the stack + # @return [void] + def process_topmost_state + if possibility + attempt_to_activate + else + create_conflict + unwind_for_conflict + end + rescue CircularDependencyError => underlying_error + create_conflict(underlying_error) + unwind_for_conflict + end + + # @return [Object] the current possibility that the resolution is trying + # to activate + def possibility + possibilities.last + end + + # @return [RequirementState] the current state the resolution is + # operating upon + def state + states.last + end + + # Creates and pushes the initial state for the resolution, based upon the + # {#requested} dependencies + # @return [void] + def push_initial_state + graph = DependencyGraph.new.tap do |dg| + original_requested.each do |requested| + vertex = dg.add_vertex(name_for(requested), nil, true) + vertex.explicit_requirements << requested + end + dg.tag(:initial_state) + end + + push_state_for_requirements(original_requested, true, graph) + end + + # Unwinds the states stack because a conflict has been encountered + # @return [void] + def unwind_for_conflict + details_for_unwind = build_details_for_unwind + unwind_options = unused_unwind_options + debug(depth) { "Unwinding for conflict: #{requirement} to #{details_for_unwind.state_index / 2}" } + conflicts.tap do |c| + sliced_states = states.slice!((details_for_unwind.state_index + 1)..-1) + raise_error_unless_state(c) + activated.rewind_to(sliced_states.first || :initial_state) if sliced_states + state.conflicts = c + state.unused_unwind_options = unwind_options + filter_possibilities_after_unwind(details_for_unwind) + index = states.size - 1 + @parents_of.each { |_, a| a.reject! { |i| i >= index } } + state.unused_unwind_options.reject! { |uw| uw.state_index >= index } + end + end + + # Raises a VersionConflict error, or any underlying error, if there is no + # current state + # @return [void] + def raise_error_unless_state(conflicts) + return if state + + error = conflicts.values.map(&:underlying_error).compact.first + raise error || VersionConflict.new(conflicts, specification_provider) + end + + # @return [UnwindDetails] Details of the nearest index to which we could unwind + def build_details_for_unwind + # Get the possible unwinds for the current conflict + current_conflict = conflicts[name] + binding_requirements = binding_requirements_for_conflict(current_conflict) + unwind_details = unwind_options_for_requirements(binding_requirements) + + last_detail_for_current_unwind = unwind_details.sort.last + current_detail = last_detail_for_current_unwind + + # Look for past conflicts that could be unwound to affect the + # requirement tree for the current conflict + all_reqs = last_detail_for_current_unwind.all_requirements + all_reqs_size = all_reqs.size + relevant_unused_unwinds = unused_unwind_options.select do |alternative| + diff_reqs = all_reqs - alternative.requirements_unwound_to_instead + next if diff_reqs.size == all_reqs_size + # Find the highest index unwind whilst looping through + current_detail = alternative if alternative > current_detail + alternative + end + + # Add the current unwind options to the `unused_unwind_options` array. + # The "used" option will be filtered out during `unwind_for_conflict`. + state.unused_unwind_options += unwind_details.reject { |detail| detail.state_index == -1 } + + # Update the requirements_unwound_to_instead on any relevant unused unwinds + relevant_unused_unwinds.each do |d| + (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq! + end + unwind_details.each do |d| + (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq! + end + + current_detail + end + + # @param [Array] binding_requirements array of requirements that combine to create a conflict + # @return [Array] array of UnwindDetails that have a chance + # of resolving the passed requirements + def unwind_options_for_requirements(binding_requirements) + unwind_details = [] + + trees = [] + binding_requirements.reverse_each do |r| + partial_tree = [r] + trees << partial_tree + unwind_details << UnwindDetails.new(-1, nil, partial_tree, binding_requirements, trees, []) + + # If this requirement has alternative possibilities, check if any would + # satisfy the other requirements that created this conflict + requirement_state = find_state_for(r) + if conflict_fixing_possibilities?(requirement_state, binding_requirements) + unwind_details << UnwindDetails.new( + states.index(requirement_state), + r, + partial_tree, + binding_requirements, + trees, + [] + ) + end + + # Next, look at the parent of this requirement, and check if the requirement + # could have been avoided if an alternative PossibilitySet had been chosen + parent_r = parent_of(r) + next if parent_r.nil? + partial_tree.unshift(parent_r) + requirement_state = find_state_for(parent_r) + if requirement_state.possibilities.any? { |set| !set.dependencies.include?(r) } + unwind_details << UnwindDetails.new( + states.index(requirement_state), + parent_r, + partial_tree, + binding_requirements, + trees, + [] + ) + end + + # Finally, look at the grandparent and up of this requirement, looking + # for any possibilities that wouldn't create their parent requirement + grandparent_r = parent_of(parent_r) + until grandparent_r.nil? + partial_tree.unshift(grandparent_r) + requirement_state = find_state_for(grandparent_r) + if requirement_state.possibilities.any? { |set| !set.dependencies.include?(parent_r) } + unwind_details << UnwindDetails.new( + states.index(requirement_state), + grandparent_r, + partial_tree, + binding_requirements, + trees, + [] + ) + end + parent_r = grandparent_r + grandparent_r = parent_of(parent_r) + end + end + + unwind_details + end + + # @param [DependencyState] state + # @param [Array] binding_requirements array of requirements + # @return [Boolean] whether or not the given state has any possibilities + # that could satisfy the given requirements + def conflict_fixing_possibilities?(state, binding_requirements) + return false unless state + + state.possibilities.any? do |possibility_set| + possibility_set.possibilities.any? do |poss| + possibility_satisfies_requirements?(poss, binding_requirements) + end + end + end + + # Filter's a state's possibilities to remove any that would not fix the + # conflict we've just rewound from + # @param [UnwindDetails] unwind_details details of the conflict just + # unwound from + # @return [void] + def filter_possibilities_after_unwind(unwind_details) + return unless state && !state.possibilities.empty? + + if unwind_details.unwinding_to_primary_requirement? + filter_possibilities_for_primary_unwind(unwind_details) + else + filter_possibilities_for_parent_unwind(unwind_details) + end + end + + # Filter's a state's possibilities to remove any that would not satisfy + # the requirements in the conflict we've just rewound from + # @param [UnwindDetails] unwind_details details of the conflict just unwound from + # @return [void] + def filter_possibilities_for_primary_unwind(unwind_details) + unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index } + unwinds_to_state << unwind_details + unwind_requirement_sets = unwinds_to_state.map(&:conflicting_requirements) + + state.possibilities.reject! do |possibility_set| + possibility_set.possibilities.none? do |poss| + unwind_requirement_sets.any? do |requirements| + possibility_satisfies_requirements?(poss, requirements) + end + end + end + end + + # @param [Object] possibility a single possibility + # @param [Array] requirements an array of requirements + # @return [Boolean] whether the possibility satisfies all of the + # given requirements + def possibility_satisfies_requirements?(possibility, requirements) + name = name_for(possibility) + + activated.tag(:swap) + activated.set_payload(name, possibility) if activated.vertex_named(name) + satisfied = requirements.all? { |r| requirement_satisfied_by?(r, activated, possibility) } + activated.rewind_to(:swap) + + satisfied + end + + # Filter's a state's possibilities to remove any that would (eventually) + # create a requirement in the conflict we've just rewound from + # @param [UnwindDetails] unwind_details details of the conflict just unwound from + # @return [void] + def filter_possibilities_for_parent_unwind(unwind_details) + unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index } + unwinds_to_state << unwind_details + + primary_unwinds = unwinds_to_state.select(&:unwinding_to_primary_requirement?).uniq + parent_unwinds = unwinds_to_state.uniq - primary_unwinds + + allowed_possibility_sets = primary_unwinds.flat_map do |unwind| + states[unwind.state_index].possibilities.select do |possibility_set| + possibility_set.possibilities.any? do |poss| + possibility_satisfies_requirements?(poss, unwind.conflicting_requirements) + end + end + end + + requirements_to_avoid = parent_unwinds.flat_map(&:sub_dependencies_to_avoid) + + state.possibilities.reject! do |possibility_set| + !allowed_possibility_sets.include?(possibility_set) && + (requirements_to_avoid - possibility_set.dependencies).empty? + end + end + + # @param [Conflict] conflict + # @return [Array] minimal array of requirements that would cause the passed + # conflict to occur. + def binding_requirements_for_conflict(conflict) + return [conflict.requirement] if conflict.possibility.nil? + + possible_binding_requirements = conflict.requirements.values.flatten(1).uniq + + # When there's a `CircularDependency` error the conflicting requirement + # (the one causing the circular) won't be `conflict.requirement` + # (which won't be for the right state, because we won't have created it, + # because it's circular). + # We need to make sure we have that requirement in the conflict's list, + # otherwise we won't be able to unwind properly, so we just return all + # the requirements for the conflict. + return possible_binding_requirements if conflict.underlying_error + + possibilities = search_for(conflict.requirement) + + # If all the requirements together don't filter out all possibilities, + # then the only two requirements we need to consider are the initial one + # (where the dependency's version was first chosen) and the last + if binding_requirement_in_set?(nil, possible_binding_requirements, possibilities) + return [conflict.requirement, requirement_for_existing_name(name_for(conflict.requirement))].compact + end + + # Loop through the possible binding requirements, removing each one + # that doesn't bind. Use a `reverse_each` as we want the earliest set of + # binding requirements, and don't use `reject!` as we wish to refine the + # array *on each iteration*. + binding_requirements = possible_binding_requirements.dup + possible_binding_requirements.reverse_each do |req| + next if req == conflict.requirement + unless binding_requirement_in_set?(req, binding_requirements, possibilities) + binding_requirements -= [req] + end + end + + binding_requirements + end + + # @param [Object] requirement we wish to check + # @param [Array] possible_binding_requirements array of requirements + # @param [Array] possibilities array of possibilities the requirements will be used to filter + # @return [Boolean] whether or not the given requirement is required to filter + # out all elements of the array of possibilities. + def binding_requirement_in_set?(requirement, possible_binding_requirements, possibilities) + possibilities.any? do |poss| + possibility_satisfies_requirements?(poss, possible_binding_requirements - [requirement]) + end + end + + # @param [Object] requirement + # @return [Object] the requirement that led to `requirement` being added + # to the list of requirements. + def parent_of(requirement) + return unless requirement + return unless index = @parents_of[requirement].last + return unless parent_state = @states[index] + parent_state.requirement + end + + # @param [String] name + # @return [Object] the requirement that led to a version of a possibility + # with the given name being activated. + def requirement_for_existing_name(name) + return nil unless vertex = activated.vertex_named(name) + return nil unless vertex.payload + states.find { |s| s.name == name }.requirement + end + + # @param [Object] requirement + # @return [ResolutionState] the state whose `requirement` is the given + # `requirement`. + def find_state_for(requirement) + return nil unless requirement + states.find { |i| requirement == i.requirement } + end + + # @param [Object] underlying_error + # @return [Conflict] a {Conflict} that reflects the failure to activate + # the {#possibility} in conjunction with the current {#state} + def create_conflict(underlying_error = nil) + vertex = activated.vertex_named(name) + locked_requirement = locked_requirement_named(name) + + requirements = {} + unless vertex.explicit_requirements.empty? + requirements[name_for_explicit_dependency_source] = vertex.explicit_requirements + end + requirements[name_for_locking_dependency_source] = [locked_requirement] if locked_requirement + vertex.incoming_edges.each do |edge| + (requirements[edge.origin.payload.latest_version] ||= []).unshift(edge.requirement) + end + + activated_by_name = {} + activated.each { |v| activated_by_name[v.name] = v.payload.latest_version if v.payload } + conflicts[name] = Conflict.new( + requirement, + requirements, + vertex.payload && vertex.payload.latest_version, + possibility, + locked_requirement, + requirement_trees, + activated_by_name, + underlying_error + ) + end + + # @return [Array>] The different requirement + # trees that led to every requirement for the current spec. + def requirement_trees + vertex = activated.vertex_named(name) + vertex.requirements.map { |r| requirement_tree_for(r) } + end + + # @param [Object] requirement + # @return [Array] the list of requirements that led to + # `requirement` being required. + def requirement_tree_for(requirement) + tree = [] + while requirement + tree.unshift(requirement) + requirement = parent_of(requirement) + end + tree + end + + # Indicates progress roughly once every second + # @return [void] + def indicate_progress + @iteration_counter += 1 + @progress_rate ||= resolver_ui.progress_rate + if iteration_rate.nil? + if Time.now - started_at >= @progress_rate + self.iteration_rate = @iteration_counter + end + end + + if iteration_rate && (@iteration_counter % iteration_rate) == 0 + resolver_ui.indicate_progress + end + end + + # Calls the {#resolver_ui}'s {UI#debug} method + # @param [Integer] depth the depth of the {#states} stack + # @param [Proc] block a block that yields a {#to_s} + # @return [void] + def debug(depth = 0, &block) + resolver_ui.debug(depth, &block) + end + + # Attempts to activate the current {#possibility} + # @return [void] + def attempt_to_activate + debug(depth) { 'Attempting to activate ' + possibility.to_s } + existing_vertex = activated.vertex_named(name) + if existing_vertex.payload + debug(depth) { "Found existing spec (#{existing_vertex.payload})" } + attempt_to_filter_existing_spec(existing_vertex) + else + latest = possibility.latest_version + possibility.possibilities.select! do |possibility| + requirement_satisfied_by?(requirement, activated, possibility) + end + if possibility.latest_version.nil? + # ensure there's a possibility for better error messages + possibility.possibilities << latest if latest + create_conflict + unwind_for_conflict + else + activate_new_spec + end + end + end + + # Attempts to update the existing vertex's `PossibilitySet` with a filtered version + # @return [void] + def attempt_to_filter_existing_spec(vertex) + filtered_set = filtered_possibility_set(vertex) + if !filtered_set.possibilities.empty? + activated.set_payload(name, filtered_set) + new_requirements = requirements.dup + push_state_for_requirements(new_requirements, false) + else + create_conflict + debug(depth) { "Unsatisfied by existing spec (#{vertex.payload})" } + unwind_for_conflict + end + end + + # Generates a filtered version of the existing vertex's `PossibilitySet` using the + # current state's `requirement` + # @param [Object] vertex existing vertex + # @return [PossibilitySet] filtered possibility set + def filtered_possibility_set(vertex) + PossibilitySet.new(vertex.payload.dependencies, vertex.payload.possibilities & possibility.possibilities) + end + + # @param [String] requirement_name the spec name to search for + # @return [Object] the locked spec named `requirement_name`, if one + # is found on {#base} + def locked_requirement_named(requirement_name) + vertex = base.vertex_named(requirement_name) + vertex && vertex.payload + end + + # Add the current {#possibility} to the dependency graph of the current + # {#state} + # @return [void] + def activate_new_spec + conflicts.delete(name) + debug(depth) { "Activated #{name} at #{possibility}" } + activated.set_payload(name, possibility) + require_nested_dependencies_for(possibility) + end + + # Requires the dependencies that the recently activated spec has + # @param [Object] possibility_set the PossibilitySet that has just been + # activated + # @return [void] + def require_nested_dependencies_for(possibility_set) + nested_dependencies = dependencies_for(possibility_set.latest_version) + debug(depth) { "Requiring nested dependencies (#{nested_dependencies.join(', ')})" } + nested_dependencies.each do |d| + activated.add_child_vertex(name_for(d), nil, [name_for(possibility_set.latest_version)], d) + parent_index = states.size - 1 + parents = @parents_of[d] + parents << parent_index if parents.empty? + end + + push_state_for_requirements(requirements + nested_dependencies, !nested_dependencies.empty?) + end + + # Pushes a new {DependencyState} that encapsulates both existing and new + # requirements + # @param [Array] new_requirements + # @param [Boolean] requires_sort + # @param [Object] new_activated + # @return [void] + def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated) + new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort + new_requirement = nil + loop do + new_requirement = new_requirements.shift + break if new_requirement.nil? || states.none? { |s| s.requirement == new_requirement } + end + new_name = new_requirement ? name_for(new_requirement) : ''.freeze + possibilities = possibilities_for_requirement(new_requirement) + handle_missing_or_push_dependency_state DependencyState.new( + new_name, new_requirements, new_activated, + new_requirement, possibilities, depth, conflicts.dup, unused_unwind_options.dup + ) + end + + # Checks a proposed requirement with any existing locked requirement + # before generating an array of possibilities for it. + # @param [Object] requirement the proposed requirement + # @param [Object] activated + # @return [Array] possibilities + def possibilities_for_requirement(requirement, activated = self.activated) + return [] unless requirement + if locked_requirement_named(name_for(requirement)) + return locked_requirement_possibility_set(requirement, activated) + end + + group_possibilities(search_for(requirement)) + end + + # @param [Object] requirement the proposed requirement + # @param [Object] activated + # @return [Array] possibility set containing only the locked requirement, if any + def locked_requirement_possibility_set(requirement, activated = self.activated) + all_possibilities = search_for(requirement) + locked_requirement = locked_requirement_named(name_for(requirement)) + + # Longwinded way to build a possibilities array with either the locked + # requirement or nothing in it. Required, since the API for + # locked_requirement isn't guaranteed. + locked_possibilities = all_possibilities.select do |possibility| + requirement_satisfied_by?(locked_requirement, activated, possibility) + end + + group_possibilities(locked_possibilities) + end + + # Build an array of PossibilitySets, with each element representing a group of + # dependency versions that all have the same sub-dependency version constraints + # and are contiguous. + # @param [Array] possibilities an array of possibilities + # @return [Array] an array of possibility sets + def group_possibilities(possibilities) + possibility_sets = [] + current_possibility_set = nil + + possibilities.reverse_each do |possibility| + dependencies = dependencies_for(possibility) + if current_possibility_set && dependencies_equal?(current_possibility_set.dependencies, dependencies) + current_possibility_set.possibilities.unshift(possibility) + else + possibility_sets.unshift(PossibilitySet.new(dependencies, [possibility])) + current_possibility_set = possibility_sets.first + end + end + + possibility_sets + end + + # Pushes a new {DependencyState}. + # If the {#specification_provider} says to + # {SpecificationProvider#allow_missing?} that particular requirement, and + # there are no possibilities for that requirement, then `state` is not + # pushed, and the vertex in {#activated} is removed, and we continue + # resolving the remaining requirements. + # @param [DependencyState] state + # @return [void] + def handle_missing_or_push_dependency_state(state) + if state.requirement && state.possibilities.empty? && allow_missing?(state.requirement) + state.activated.detach_vertex_named(state.name) + push_state_for_requirements(state.requirements.dup, false, state.activated) + else + states.push(state).tap { activated.tag(state) } + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/resolver.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/resolver.rb new file mode 100644 index 0000000..95eaab5 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/resolver.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require_relative 'dependency_graph' + +module Bundler::Molinillo + # This class encapsulates a dependency resolver. + # The resolver is responsible for determining which set of dependencies to + # activate, with feedback from the {#specification_provider} + # + # + class Resolver + require_relative 'resolution' + + # @return [SpecificationProvider] the specification provider used + # in the resolution process + attr_reader :specification_provider + + # @return [UI] the UI module used to communicate back to the user + # during the resolution process + attr_reader :resolver_ui + + # Initializes a new resolver. + # @param [SpecificationProvider] specification_provider + # see {#specification_provider} + # @param [UI] resolver_ui + # see {#resolver_ui} + def initialize(specification_provider, resolver_ui) + @specification_provider = specification_provider + @resolver_ui = resolver_ui + end + + # Resolves the requested dependencies into a {DependencyGraph}, + # locking to the base dependency graph (if specified) + # @param [Array] requested an array of 'requested' dependencies that the + # {#specification_provider} can understand + # @param [DependencyGraph,nil] base the base dependency graph to which + # dependencies should be 'locked' + def resolve(requested, base = DependencyGraph.new) + Resolution.new(specification_provider, + resolver_ui, + requested, + base). + resolve + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/state.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/state.rb new file mode 100644 index 0000000..68fa1f5 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/molinillo/lib/molinillo/state.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +module Bundler::Molinillo + # A state that a {Resolution} can be in + # @attr [String] name the name of the current requirement + # @attr [Array] requirements currently unsatisfied requirements + # @attr [DependencyGraph] activated the graph of activated dependencies + # @attr [Object] requirement the current requirement + # @attr [Object] possibilities the possibilities to satisfy the current requirement + # @attr [Integer] depth the depth of the resolution + # @attr [Hash] conflicts unresolved conflicts, indexed by dependency name + # @attr [Array] unused_unwind_options unwinds for previous conflicts that weren't explored + ResolutionState = Struct.new( + :name, + :requirements, + :activated, + :requirement, + :possibilities, + :depth, + :conflicts, + :unused_unwind_options + ) + + class ResolutionState + # Returns an empty resolution state + # @return [ResolutionState] an empty state + def self.empty + new(nil, [], DependencyGraph.new, nil, nil, 0, {}, []) + end + end + + # A state that encapsulates a set of {#requirements} with an {Array} of + # possibilities + class DependencyState < ResolutionState + # Removes a possibility from `self` + # @return [PossibilityState] a state with a single possibility, + # the possibility that was removed from `self` + def pop_possibility_state + PossibilityState.new( + name, + requirements.dup, + activated, + requirement, + [possibilities.pop], + depth + 1, + conflicts.dup, + unused_unwind_options.dup + ).tap do |state| + state.activated.tag(state) + end + end + end + + # A state that encapsulates a single possibility to fulfill the given + # {#requirement} + class PossibilityState < ResolutionState + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb new file mode 100644 index 0000000..beff6d6 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb @@ -0,0 +1,1073 @@ +require 'net/http' +require_relative '../../../../uri/lib/uri' +require 'cgi' # for escaping +require_relative '../../../../connection_pool/lib/connection_pool' + +autoload :OpenSSL, 'openssl' + +## +# Persistent connections for Net::HTTP +# +# Bundler::Persistent::Net::HTTP::Persistent maintains persistent connections across all the +# servers you wish to talk to. For each host:port you communicate with a +# single persistent connection is created. +# +# Connections will be shared across threads through a connection pool to +# increase reuse of connections. +# +# You can shut down any remaining HTTP connections when done by calling +# #shutdown. +# +# Example: +# +# require 'bundler/vendor/net-http-persistent/lib/net/http/persistent' +# +# uri = Bundler::URI 'http://example.com/awesome/web/service' +# +# http = Bundler::Persistent::Net::HTTP::Persistent.new +# +# # perform a GET +# response = http.request uri +# +# # or +# +# get = Net::HTTP::Get.new uri.request_uri +# response = http.request get +# +# # create a POST +# post_uri = uri + 'create' +# post = Net::HTTP::Post.new post_uri.path +# post.set_form_data 'some' => 'cool data' +# +# # perform the POST, the Bundler::URI is always required +# response http.request post_uri, post +# +# Note that for GET, HEAD and other requests that do not have a body you want +# to use Bundler::URI#request_uri not Bundler::URI#path. The request_uri contains the query +# params which are sent in the body for other requests. +# +# == TLS/SSL +# +# TLS connections are automatically created depending upon the scheme of the +# Bundler::URI. TLS connections are automatically verified against the default +# certificate store for your computer. You can override this by changing +# verify_mode or by specifying an alternate cert_store. +# +# Here are the TLS settings, see the individual methods for documentation: +# +# #certificate :: This client's certificate +# #ca_file :: The certificate-authorities +# #ca_path :: Directory with certificate-authorities +# #cert_store :: An SSL certificate store +# #ciphers :: List of SSl ciphers allowed +# #private_key :: The client's SSL private key +# #reuse_ssl_sessions :: Reuse a previously opened SSL session for a new +# connection +# #ssl_timeout :: Session lifetime +# #ssl_version :: Which specific SSL version to use +# #verify_callback :: For server certificate verification +# #verify_depth :: Depth of certificate verification +# #verify_mode :: How connections should be verified +# +# == Proxies +# +# A proxy can be set through #proxy= or at initialization time by providing a +# second argument to ::new. The proxy may be the Bundler::URI of the proxy server or +# :ENV which will consult environment variables. +# +# See #proxy= and #proxy_from_env for details. +# +# == Headers +# +# Headers may be specified for use in every request. #headers are appended to +# any headers on the request. #override_headers replace existing headers on +# the request. +# +# The difference between the two can be seen in setting the User-Agent. Using +# http.headers['User-Agent'] = 'MyUserAgent' will send "Ruby, +# MyUserAgent" while http.override_headers['User-Agent'] = +# 'MyUserAgent' will send "MyUserAgent". +# +# == Tuning +# +# === Segregation +# +# Each Bundler::Persistent::Net::HTTP::Persistent instance has its own pool of connections. There +# is no sharing with other instances (as was true in earlier versions). +# +# === Idle Timeout +# +# If a connection hasn't been used for this number of seconds it will +# automatically be reset upon the next use to avoid attempting to send to a +# closed connection. The default value is 5 seconds. nil means no timeout. +# Set through #idle_timeout. +# +# Reducing this value may help avoid the "too many connection resets" error +# when sending non-idempotent requests while increasing this value will cause +# fewer round-trips. +# +# === Read Timeout +# +# The amount of time allowed between reading two chunks from the socket. Set +# through #read_timeout +# +# === Max Requests +# +# The number of requests that should be made before opening a new connection. +# Typically many keep-alive capable servers tune this to 100 or less, so the +# 101st request will fail with ECONNRESET. If unset (default), this value has +# no effect, if set, connections will be reset on the request after +# max_requests. +# +# === Open Timeout +# +# The amount of time to wait for a connection to be opened. Set through +# #open_timeout. +# +# === Socket Options +# +# Socket options may be set on newly-created connections. See #socket_options +# for details. +# +# === Connection Termination +# +# If you are done using the Bundler::Persistent::Net::HTTP::Persistent instance you may shut down +# all the connections in the current thread with #shutdown. This is not +# recommended for normal use, it should only be used when it will be several +# minutes before you make another HTTP request. +# +# If you are using multiple threads, call #shutdown in each thread when the +# thread is done making requests. If you don't call shutdown, that's OK. +# Ruby will automatically garbage collect and shutdown your HTTP connections +# when the thread terminates. + +class Bundler::Persistent::Net::HTTP::Persistent + + ## + # The beginning of Time + + EPOCH = Time.at 0 # :nodoc: + + ## + # Is OpenSSL available? This test works with autoload + + HAVE_OPENSSL = defined? OpenSSL::SSL # :nodoc: + + ## + # The default connection pool size is 1/4 the allowed open files + # (ulimit -n) or 256 if your OS does not support file handle + # limits (typically windows). + + if Process.const_defined? :RLIMIT_NOFILE + open_file_limits = Process.getrlimit(Process::RLIMIT_NOFILE) + + # Under JRuby on Windows Process responds to `getrlimit` but returns something that does not match docs + if open_file_limits.respond_to?(:first) + DEFAULT_POOL_SIZE = open_file_limits.first / 4 + else + DEFAULT_POOL_SIZE = 256 + end + else + DEFAULT_POOL_SIZE = 256 + end + + ## + # The version of Bundler::Persistent::Net::HTTP::Persistent you are using + + VERSION = '4.0.0' + + ## + # Error class for errors raised by Bundler::Persistent::Net::HTTP::Persistent. Various + # SystemCallErrors are re-raised with a human-readable message under this + # class. + + class Error < StandardError; end + + ## + # Use this method to detect the idle timeout of the host at +uri+. The + # value returned can be used to configure #idle_timeout. +max+ controls the + # maximum idle timeout to detect. + # + # After + # + # Idle timeout detection is performed by creating a connection then + # performing a HEAD request in a loop until the connection terminates + # waiting one additional second per loop. + # + # NOTE: This may not work on ruby > 1.9. + + def self.detect_idle_timeout uri, max = 10 + uri = Bundler::URI uri unless Bundler::URI::Generic === uri + uri += '/' + + req = Net::HTTP::Head.new uri.request_uri + + http = new 'net-http-persistent detect_idle_timeout' + + http.connection_for uri do |connection| + sleep_time = 0 + + http = connection.http + + loop do + response = http.request req + + $stderr.puts "HEAD #{uri} => #{response.code}" if $DEBUG + + unless Net::HTTPOK === response then + raise Error, "bad response code #{response.code} detecting idle timeout" + end + + break if sleep_time >= max + + sleep_time += 1 + + $stderr.puts "sleeping #{sleep_time}" if $DEBUG + sleep sleep_time + end + end + rescue + # ignore StandardErrors, we've probably found the idle timeout. + ensure + return sleep_time unless $! + end + + ## + # This client's OpenSSL::X509::Certificate + + attr_reader :certificate + + ## + # For Net::HTTP parity + + alias cert certificate + + ## + # An SSL certificate authority. Setting this will set verify_mode to + # VERIFY_PEER. + + attr_reader :ca_file + + ## + # A directory of SSL certificates to be used as certificate authorities. + # Setting this will set verify_mode to VERIFY_PEER. + + attr_reader :ca_path + + ## + # An SSL certificate store. Setting this will override the default + # certificate store. See verify_mode for more information. + + attr_reader :cert_store + + ## + # The ciphers allowed for SSL connections + + attr_reader :ciphers + + ## + # Sends debug_output to this IO via Net::HTTP#set_debug_output. + # + # Never use this method in production code, it causes a serious security + # hole. + + attr_accessor :debug_output + + ## + # Current connection generation + + attr_reader :generation # :nodoc: + + ## + # Headers that are added to every request using Net::HTTP#add_field + + attr_reader :headers + + ## + # Maps host:port to an HTTP version. This allows us to enable version + # specific features. + + attr_reader :http_versions + + ## + # Maximum time an unused connection can remain idle before being + # automatically closed. + + attr_accessor :idle_timeout + + ## + # Maximum number of requests on a connection before it is considered expired + # and automatically closed. + + attr_accessor :max_requests + + ## + # Number of retries to perform if a request fails. + # + # See also #max_retries=, Net::HTTP#max_retries=. + + attr_reader :max_retries + + ## + # The value sent in the Keep-Alive header. Defaults to 30. Not needed for + # HTTP/1.1 servers. + # + # This may not work correctly for HTTP/1.0 servers + # + # This method may be removed in a future version as RFC 2616 does not + # require this header. + + attr_accessor :keep_alive + + ## + # The name for this collection of persistent connections. + + attr_reader :name + + ## + # Seconds to wait until a connection is opened. See Net::HTTP#open_timeout + + attr_accessor :open_timeout + + ## + # Headers that are added to every request using Net::HTTP#[]= + + attr_reader :override_headers + + ## + # This client's SSL private key + + attr_reader :private_key + + ## + # For Net::HTTP parity + + alias key private_key + + ## + # The URL through which requests will be proxied + + attr_reader :proxy_uri + + ## + # List of host suffixes which will not be proxied + + attr_reader :no_proxy + + ## + # Test-only accessor for the connection pool + + attr_reader :pool # :nodoc: + + ## + # Seconds to wait until reading one block. See Net::HTTP#read_timeout + + attr_accessor :read_timeout + + ## + # Seconds to wait until writing one block. See Net::HTTP#write_timeout + + attr_accessor :write_timeout + + ## + # By default SSL sessions are reused to avoid extra SSL handshakes. Set + # this to false if you have problems communicating with an HTTPS server + # like: + # + # SSL_connect [...] read finished A: unexpected message (OpenSSL::SSL::SSLError) + + attr_accessor :reuse_ssl_sessions + + ## + # An array of options for Socket#setsockopt. + # + # By default the TCP_NODELAY option is set on sockets. + # + # To set additional options append them to this array: + # + # http.socket_options << [Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1] + + attr_reader :socket_options + + ## + # Current SSL connection generation + + attr_reader :ssl_generation # :nodoc: + + ## + # SSL session lifetime + + attr_reader :ssl_timeout + + ## + # SSL version to use. + # + # By default, the version will be negotiated automatically between client + # and server. Ruby 1.9 and newer only. Deprecated since Ruby 2.5. + + attr_reader :ssl_version + + ## + # Minimum SSL version to use, e.g. :TLS1_1 + # + # By default, the version will be negotiated automatically between client + # and server. Ruby 2.5 and newer only. + + attr_reader :min_version + + ## + # Maximum SSL version to use, e.g. :TLS1_2 + # + # By default, the version will be negotiated automatically between client + # and server. Ruby 2.5 and newer only. + + attr_reader :max_version + + ## + # Where this instance's last-use times live in the thread local variables + + attr_reader :timeout_key # :nodoc: + + ## + # SSL verification callback. Used when ca_file or ca_path is set. + + attr_reader :verify_callback + + ## + # Sets the depth of SSL certificate verification + + attr_reader :verify_depth + + ## + # HTTPS verify mode. Defaults to OpenSSL::SSL::VERIFY_PEER which verifies + # the server certificate. + # + # If no ca_file, ca_path or cert_store is set the default system certificate + # store is used. + # + # You can use +verify_mode+ to override any default values. + + attr_reader :verify_mode + + ## + # Creates a new Bundler::Persistent::Net::HTTP::Persistent. + # + # Set a +name+ for fun. Your library name should be good enough, but this + # otherwise has no purpose. + # + # +proxy+ may be set to a Bundler::URI::HTTP or :ENV to pick up proxy options from + # the environment. See proxy_from_env for details. + # + # In order to use a Bundler::URI for the proxy you may need to do some extra work + # beyond Bundler::URI parsing if the proxy requires a password: + # + # proxy = Bundler::URI 'http://proxy.example' + # proxy.user = 'AzureDiamond' + # proxy.password = 'hunter2' + # + # Set +pool_size+ to limit the maximum number of connections allowed. + # Defaults to 1/4 the number of allowed file handles or 256 if your OS does + # not support a limit on allowed file handles. You can have no more than + # this many threads with active HTTP transactions. + + def initialize name: nil, proxy: nil, pool_size: DEFAULT_POOL_SIZE + @name = name + + @debug_output = nil + @proxy_uri = nil + @no_proxy = [] + @headers = {} + @override_headers = {} + @http_versions = {} + @keep_alive = 30 + @open_timeout = nil + @read_timeout = nil + @write_timeout = nil + @idle_timeout = 5 + @max_requests = nil + @max_retries = 1 + @socket_options = [] + @ssl_generation = 0 # incremented when SSL session variables change + + @socket_options << [Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1] if + Socket.const_defined? :TCP_NODELAY + + @pool = Bundler::Persistent::Net::HTTP::Persistent::Pool.new size: pool_size do |http_args| + Bundler::Persistent::Net::HTTP::Persistent::Connection.new Net::HTTP, http_args, @ssl_generation + end + + @certificate = nil + @ca_file = nil + @ca_path = nil + @ciphers = nil + @private_key = nil + @ssl_timeout = nil + @ssl_version = nil + @min_version = nil + @max_version = nil + @verify_callback = nil + @verify_depth = nil + @verify_mode = nil + @cert_store = nil + + @generation = 0 # incremented when proxy Bundler::URI changes + + if HAVE_OPENSSL then + @verify_mode = OpenSSL::SSL::VERIFY_PEER + @reuse_ssl_sessions = OpenSSL::SSL.const_defined? :Session + end + + self.proxy = proxy if proxy + end + + ## + # Sets this client's OpenSSL::X509::Certificate + + def certificate= certificate + @certificate = certificate + + reconnect_ssl + end + + # For Net::HTTP parity + alias cert= certificate= + + ## + # Sets the SSL certificate authority file. + + def ca_file= file + @ca_file = file + + reconnect_ssl + end + + ## + # Sets the SSL certificate authority path. + + def ca_path= path + @ca_path = path + + reconnect_ssl + end + + ## + # Overrides the default SSL certificate store used for verifying + # connections. + + def cert_store= store + @cert_store = store + + reconnect_ssl + end + + ## + # The ciphers allowed for SSL connections + + def ciphers= ciphers + @ciphers = ciphers + + reconnect_ssl + end + + ## + # Creates a new connection for +uri+ + + def connection_for uri + use_ssl = uri.scheme.downcase == 'https' + + net_http_args = [uri.hostname, uri.port] + + # I'm unsure if uri.host or uri.hostname should be checked against + # the proxy bypass list. + if @proxy_uri and not proxy_bypass? uri.host, uri.port then + net_http_args.concat @proxy_args + else + net_http_args.concat [nil, nil, nil, nil] + end + + connection = @pool.checkout net_http_args + + http = connection.http + + connection.ressl @ssl_generation if + connection.ssl_generation != @ssl_generation + + if not http.started? then + ssl http if use_ssl + start http + elsif expired? connection then + reset connection + end + + http.keep_alive_timeout = @idle_timeout if @idle_timeout + http.max_retries = @max_retries if http.respond_to?(:max_retries=) + http.read_timeout = @read_timeout if @read_timeout + http.write_timeout = @write_timeout if + @write_timeout && http.respond_to?(:write_timeout=) + + return yield connection + rescue Errno::ECONNREFUSED + address = http.proxy_address || http.address + port = http.proxy_port || http.port + + raise Error, "connection refused: #{address}:#{port}" + rescue Errno::EHOSTDOWN + address = http.proxy_address || http.address + port = http.proxy_port || http.port + + raise Error, "host down: #{address}:#{port}" + ensure + @pool.checkin net_http_args + end + + ## + # CGI::escape wrapper + + def escape str + CGI.escape str if str + end + + ## + # CGI::unescape wrapper + + def unescape str + CGI.unescape str if str + end + + + ## + # Returns true if the connection should be reset due to an idle timeout, or + # maximum request count, false otherwise. + + def expired? connection + return true if @max_requests && connection.requests >= @max_requests + return false unless @idle_timeout + return true if @idle_timeout.zero? + + Time.now - connection.last_use > @idle_timeout + end + + ## + # Starts the Net::HTTP +connection+ + + def start http + http.set_debug_output @debug_output if @debug_output + http.open_timeout = @open_timeout if @open_timeout + + http.start + + socket = http.instance_variable_get :@socket + + if socket then # for fakeweb + @socket_options.each do |option| + socket.io.setsockopt(*option) + end + end + end + + ## + # Finishes the Net::HTTP +connection+ + + def finish connection + connection.finish + + connection.http.instance_variable_set :@last_communicated, nil + connection.http.instance_variable_set :@ssl_session, nil unless + @reuse_ssl_sessions + end + + ## + # Returns the HTTP protocol version for +uri+ + + def http_version uri + @http_versions["#{uri.hostname}:#{uri.port}"] + end + + ## + # Adds "http://" to the String +uri+ if it is missing. + + def normalize_uri uri + (uri =~ /^https?:/) ? uri : "http://#{uri}" + end + + ## + # Set the maximum number of retries for a request. + # + # Defaults to one retry. + # + # Set this to 0 to disable retries. + + def max_retries= retries + retries = retries.to_int + + raise ArgumentError, "max_retries must be positive" if retries < 0 + + @max_retries = retries + + reconnect + end + + ## + # Sets this client's SSL private key + + def private_key= key + @private_key = key + + reconnect_ssl + end + + # For Net::HTTP parity + alias key= private_key= + + ## + # Sets the proxy server. The +proxy+ may be the Bundler::URI of the proxy server, + # the symbol +:ENV+ which will read the proxy from the environment or nil to + # disable use of a proxy. See #proxy_from_env for details on setting the + # proxy from the environment. + # + # If the proxy Bundler::URI is set after requests have been made, the next request + # will shut-down and re-open all connections. + # + # The +no_proxy+ query parameter can be used to specify hosts which shouldn't + # be reached via proxy; if set it should be a comma separated list of + # hostname suffixes, optionally with +:port+ appended, for example + # example.com,some.host:8080. + + def proxy= proxy + @proxy_uri = case proxy + when :ENV then proxy_from_env + when Bundler::URI::HTTP then proxy + when nil then # ignore + else raise ArgumentError, 'proxy must be :ENV or a Bundler::URI::HTTP' + end + + @no_proxy.clear + + if @proxy_uri then + @proxy_args = [ + @proxy_uri.hostname, + @proxy_uri.port, + unescape(@proxy_uri.user), + unescape(@proxy_uri.password), + ] + + @proxy_connection_id = [nil, *@proxy_args].join ':' + + if @proxy_uri.query then + @no_proxy = CGI.parse(@proxy_uri.query)['no_proxy'].join(',').downcase.split(',').map { |x| x.strip }.reject { |x| x.empty? } + end + end + + reconnect + reconnect_ssl + end + + ## + # Creates a Bundler::URI for an HTTP proxy server from ENV variables. + # + # If +HTTP_PROXY+ is set a proxy will be returned. + # + # If +HTTP_PROXY_USER+ or +HTTP_PROXY_PASS+ are set the Bundler::URI is given the + # indicated user and password unless HTTP_PROXY contains either of these in + # the Bundler::URI. + # + # The +NO_PROXY+ ENV variable can be used to specify hosts which shouldn't + # be reached via proxy; if set it should be a comma separated list of + # hostname suffixes, optionally with +:port+ appended, for example + # example.com,some.host:8080. When set to * no proxy will + # be returned. + # + # For Windows users, lowercase ENV variables are preferred over uppercase ENV + # variables. + + def proxy_from_env + env_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY'] + + return nil if env_proxy.nil? or env_proxy.empty? + + uri = Bundler::URI normalize_uri env_proxy + + env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY'] + + # '*' is special case for always bypass + return nil if env_no_proxy == '*' + + if env_no_proxy then + uri.query = "no_proxy=#{escape(env_no_proxy)}" + end + + unless uri.user or uri.password then + uri.user = escape ENV['http_proxy_user'] || ENV['HTTP_PROXY_USER'] + uri.password = escape ENV['http_proxy_pass'] || ENV['HTTP_PROXY_PASS'] + end + + uri + end + + ## + # Returns true when proxy should by bypassed for host. + + def proxy_bypass? host, port + host = host.downcase + host_port = [host, port].join ':' + + @no_proxy.each do |name| + return true if host[-name.length, name.length] == name or + host_port[-name.length, name.length] == name + end + + false + end + + ## + # Forces reconnection of all HTTP connections, including TLS/SSL + # connections. + + def reconnect + @generation += 1 + end + + ## + # Forces reconnection of only TLS/SSL connections. + + def reconnect_ssl + @ssl_generation += 1 + end + + ## + # Finishes then restarts the Net::HTTP +connection+ + + def reset connection + http = connection.http + + finish connection + + start http + rescue Errno::ECONNREFUSED + e = Error.new "connection refused: #{http.address}:#{http.port}" + e.set_backtrace $@ + raise e + rescue Errno::EHOSTDOWN + e = Error.new "host down: #{http.address}:#{http.port}" + e.set_backtrace $@ + raise e + end + + ## + # Makes a request on +uri+. If +req+ is nil a Net::HTTP::Get is performed + # against +uri+. + # + # If a block is passed #request behaves like Net::HTTP#request (the body of + # the response will not have been read). + # + # +req+ must be a Net::HTTPGenericRequest subclass (see Net::HTTP for a list). + + def request uri, req = nil, &block + uri = Bundler::URI uri + req = request_setup req || uri + response = nil + + connection_for uri do |connection| + http = connection.http + + begin + connection.requests += 1 + + response = http.request req, &block + + if req.connection_close? or + (response.http_version <= '1.0' and + not response.connection_keep_alive?) or + response.connection_close? then + finish connection + end + rescue Exception # make sure to close the connection when it was interrupted + finish connection + + raise + ensure + connection.last_use = Time.now + end + end + + @http_versions["#{uri.hostname}:#{uri.port}"] ||= response.http_version + + response + end + + ## + # Creates a GET request if +req_or_uri+ is a Bundler::URI and adds headers to the + # request. + # + # Returns the request. + + def request_setup req_or_uri # :nodoc: + req = if req_or_uri.respond_to? 'request_uri' then + Net::HTTP::Get.new req_or_uri.request_uri + else + req_or_uri + end + + @headers.each do |pair| + req.add_field(*pair) + end + + @override_headers.each do |name, value| + req[name] = value + end + + unless req['Connection'] then + req.add_field 'Connection', 'keep-alive' + req.add_field 'Keep-Alive', @keep_alive + end + + req + end + + ## + # Shuts down all connections + # + # *NOTE*: Calling shutdown for can be dangerous! + # + # If any thread is still using a connection it may cause an error! Call + # #shutdown when you are completely done making requests! + + def shutdown + @pool.shutdown { |http| http.finish } + end + + ## + # Enables SSL on +connection+ + + def ssl connection + connection.use_ssl = true + + connection.ciphers = @ciphers if @ciphers + connection.ssl_timeout = @ssl_timeout if @ssl_timeout + connection.ssl_version = @ssl_version if @ssl_version + connection.min_version = @min_version if @min_version + connection.max_version = @max_version if @max_version + + connection.verify_depth = @verify_depth + connection.verify_mode = @verify_mode + + if OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE and + not Object.const_defined?(:I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG) then + warn <<-WARNING + !!!SECURITY WARNING!!! + +The SSL HTTP connection to: + + #{connection.address}:#{connection.port} + + !!!MAY NOT BE VERIFIED!!! + +On your platform your OpenSSL implementation is broken. + +There is no difference between the values of VERIFY_NONE and VERIFY_PEER. + +This means that attempting to verify the security of SSL connections may not +work. This exposes you to man-in-the-middle exploits, snooping on the +contents of your connection and other dangers to the security of your data. + +To disable this warning define the following constant at top-level in your +application: + + I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG = nil + + WARNING + end + + connection.ca_file = @ca_file if @ca_file + connection.ca_path = @ca_path if @ca_path + + if @ca_file or @ca_path then + connection.verify_mode = OpenSSL::SSL::VERIFY_PEER + connection.verify_callback = @verify_callback if @verify_callback + end + + if @certificate and @private_key then + connection.cert = @certificate + connection.key = @private_key + end + + connection.cert_store = if @cert_store then + @cert_store + else + store = OpenSSL::X509::Store.new + store.set_default_paths + store + end + end + + ## + # SSL session lifetime + + def ssl_timeout= ssl_timeout + @ssl_timeout = ssl_timeout + + reconnect_ssl + end + + ## + # SSL version to use + + def ssl_version= ssl_version + @ssl_version = ssl_version + + reconnect_ssl + end + + ## + # Minimum SSL version to use + + def min_version= min_version + @min_version = min_version + + reconnect_ssl + end + + ## + # maximum SSL version to use + + def max_version= max_version + @max_version = max_version + + reconnect_ssl + end + + ## + # Sets the depth of SSL certificate verification + + def verify_depth= verify_depth + @verify_depth = verify_depth + + reconnect_ssl + end + + ## + # Sets the HTTPS verify mode. Defaults to OpenSSL::SSL::VERIFY_PEER. + # + # Setting this to VERIFY_NONE is a VERY BAD IDEA and should NEVER be used. + # Securely transfer the correct certificate and update the default + # certificate store or set the ca file instead. + + def verify_mode= verify_mode + @verify_mode = verify_mode + + reconnect_ssl + end + + ## + # SSL verification callback. + + def verify_callback= callback + @verify_callback = callback + + reconnect_ssl + end +end + +require_relative 'persistent/connection' +require_relative 'persistent/pool' + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb new file mode 100644 index 0000000..a57a5d1 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb @@ -0,0 +1,40 @@ +## +# A Net::HTTP connection wrapper that holds extra information for managing the +# connection's lifetime. + +class Bundler::Persistent::Net::HTTP::Persistent::Connection # :nodoc: + + attr_accessor :http + + attr_accessor :last_use + + attr_accessor :requests + + attr_accessor :ssl_generation + + def initialize http_class, http_args, ssl_generation + @http = http_class.new(*http_args) + @ssl_generation = ssl_generation + + reset + end + + def finish + @http.finish + rescue IOError + ensure + reset + end + + def reset + @last_use = Bundler::Persistent::Net::HTTP::Persistent::EPOCH + @requests = 0 + end + + def ressl ssl_generation + @ssl_generation = ssl_generation + + finish + end + +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb new file mode 100644 index 0000000..9dfa6ff --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb @@ -0,0 +1,53 @@ +class Bundler::Persistent::Net::HTTP::Persistent::Pool < Bundler::ConnectionPool # :nodoc: + + attr_reader :available # :nodoc: + attr_reader :key # :nodoc: + + def initialize(options = {}, &block) + super + + @available = Bundler::Persistent::Net::HTTP::Persistent::TimedStackMulti.new(@size, &block) + @key = "current-#{@available.object_id}" + end + + def checkin net_http_args + stack = Thread.current[@key][net_http_args] ||= [] + + raise Bundler::ConnectionPool::Error, 'no connections are checked out' if + stack.empty? + + conn = stack.pop + + if stack.empty? + @available.push conn, connection_args: net_http_args + + Thread.current[@key].delete(net_http_args) + Thread.current[@key] = nil if Thread.current[@key].empty? + end + + nil + end + + def checkout net_http_args + stacks = Thread.current[@key] ||= {} + stack = stacks[net_http_args] ||= [] + + if stack.empty? then + conn = @available.pop connection_args: net_http_args + else + conn = stack.last + end + + stack.push conn + + conn + end + + def shutdown + Thread.current[@key] = nil + super + end +end + +require_relative 'timed_stack_multi' + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb new file mode 100644 index 0000000..2da881c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb @@ -0,0 +1,79 @@ +class Bundler::Persistent::Net::HTTP::Persistent::TimedStackMulti < Bundler::ConnectionPool::TimedStack # :nodoc: + + ## + # Returns a new hash that has arrays for keys + # + # Using a class method to limit the bindings referenced by the hash's + # default_proc + + def self.hash_of_arrays # :nodoc: + Hash.new { |h,k| h[k] = [] } + end + + def initialize(size = 0, &block) + super + + @enqueued = 0 + @ques = self.class.hash_of_arrays + @lru = {} + @key = :"connection_args-#{object_id}" + end + + def empty? + (@created - @enqueued) >= @max + end + + def length + @max - @created + @enqueued + end + + private + + def connection_stored? options = {} # :nodoc: + !@ques[options[:connection_args]].empty? + end + + def fetch_connection options = {} # :nodoc: + connection_args = options[:connection_args] + + @enqueued -= 1 + lru_update connection_args + @ques[connection_args].pop + end + + def lru_update connection_args # :nodoc: + @lru.delete connection_args + @lru[connection_args] = true + end + + def shutdown_connections # :nodoc: + @ques.each_key do |key| + super connection_args: key + end + end + + def store_connection obj, options = {} # :nodoc: + @ques[options[:connection_args]].push obj + @enqueued += 1 + end + + def try_create options = {} # :nodoc: + connection_args = options[:connection_args] + + if @created >= @max && @enqueued >= 1 + oldest, = @lru.first + @lru.delete oldest + @ques[oldest].pop + + @created -= 1 + end + + if @created < @max + @created += 1 + lru_update connection_args + return @create_block.call(connection_args) + end + end + +end + diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor.rb new file mode 100644 index 0000000..0794dbb --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor.rb @@ -0,0 +1,516 @@ +require_relative "thor/base" + +class Bundler::Thor + $thor_runner ||= false + class << self + # Allows for custom "Command" package naming. + # + # === Parameters + # name + # options + # + def package_name(name, _ = {}) + @package_name = name.nil? || name == "" ? nil : name + end + + # Sets the default command when thor is executed without an explicit command to be called. + # + # ==== Parameters + # meth:: name of the default command + # + def default_command(meth = nil) + if meth + @default_command = meth == :none ? "help" : meth.to_s + else + @default_command ||= from_superclass(:default_command, "help") + end + end + alias_method :default_task, :default_command + + # Registers another Bundler::Thor subclass as a command. + # + # ==== Parameters + # klass:: Bundler::Thor subclass to register + # command:: Subcommand name to use + # usage:: Short usage for the subcommand + # description:: Description for the subcommand + def register(klass, subcommand_name, usage, description, options = {}) + if klass <= Bundler::Thor::Group + desc usage, description, options + define_method(subcommand_name) { |*args| invoke(klass, args) } + else + desc usage, description, options + subcommand subcommand_name, klass + end + end + + # Defines the usage and the description of the next command. + # + # ==== Parameters + # usage + # description + # options + # + def desc(usage, description, options = {}) + if options[:for] + command = find_and_refresh_command(options[:for]) + command.usage = usage if usage + command.description = description if description + else + @usage = usage + @desc = description + @hide = options[:hide] || false + end + end + + # Defines the long description of the next command. + # + # ==== Parameters + # long description + # + def long_desc(long_description, options = {}) + if options[:for] + command = find_and_refresh_command(options[:for]) + command.long_description = long_description if long_description + else + @long_desc = long_description + end + end + + # Maps an input to a command. If you define: + # + # map "-T" => "list" + # + # Running: + # + # thor -T + # + # Will invoke the list command. + # + # ==== Parameters + # Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given command. + # + def map(mappings = nil, **kw) + @map ||= from_superclass(:map, {}) + + if mappings && !kw.empty? + mappings = kw.merge!(mappings) + else + mappings ||= kw + end + if mappings + mappings.each do |key, value| + if key.respond_to?(:each) + key.each { |subkey| @map[subkey] = value } + else + @map[key] = value + end + end + end + + @map + end + + # Declares the options for the next command to be declared. + # + # ==== Parameters + # Hash[Symbol => Object]:: The hash key is the name of the option and the value + # is the type of the option. Can be :string, :array, :hash, :boolean, :numeric + # or :required (string). If you give a value, the type of the value is used. + # + def method_options(options = nil) + @method_options ||= {} + build_options(options, @method_options) if options + @method_options + end + + alias_method :options, :method_options + + # Adds an option to the set of method options. If :for is given as option, + # it allows you to change the options from a previous defined command. + # + # def previous_command + # # magic + # end + # + # method_option :foo => :bar, :for => :previous_command + # + # def next_command + # # magic + # end + # + # ==== Parameters + # name:: The name of the argument. + # options:: Described below. + # + # ==== Options + # :desc - Description for the argument. + # :required - If the argument is required or not. + # :default - Default value for this argument. It cannot be required and have default values. + # :aliases - Aliases for this option. + # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean. + # :banner - String to show on usage notes. + # :hide - If you want to hide this option from the help. + # + def method_option(name, options = {}) + scope = if options[:for] + find_and_refresh_command(options[:for]).options + else + method_options + end + + build_option(name, options, scope) + end + alias_method :option, :method_option + + # Prints help information for the given command. + # + # ==== Parameters + # shell + # command_name + # + def command_help(shell, command_name) + meth = normalize_command_name(command_name) + command = all_commands[meth] + handle_no_command_error(meth) unless command + + shell.say "Usage:" + shell.say " #{banner(command).split("\n").join("\n ")}" + shell.say + class_options_help(shell, nil => command.options.values) + if command.long_description + shell.say "Description:" + shell.print_wrapped(command.long_description, :indent => 2) + else + shell.say command.description + end + end + alias_method :task_help, :command_help + + # Prints help information for this class. + # + # ==== Parameters + # shell + # + def help(shell, subcommand = false) + list = printable_commands(true, subcommand) + Bundler::Thor::Util.thor_classes_in(self).each do |klass| + list += klass.printable_commands(false) + end + list.sort! { |a, b| a[0] <=> b[0] } + + if defined?(@package_name) && @package_name + shell.say "#{@package_name} commands:" + else + shell.say "Commands:" + end + + shell.print_table(list, :indent => 2, :truncate => true) + shell.say + class_options_help(shell) + end + + # Returns commands ready to be printed. + def printable_commands(all = true, subcommand = false) + (all ? all_commands : commands).map do |_, command| + next if command.hidden? + item = [] + item << banner(command, false, subcommand) + item << (command.description ? "# #{command.description.gsub(/\s+/m, ' ')}" : "") + item + end.compact + end + alias_method :printable_tasks, :printable_commands + + def subcommands + @subcommands ||= from_superclass(:subcommands, []) + end + alias_method :subtasks, :subcommands + + def subcommand_classes + @subcommand_classes ||= {} + end + + def subcommand(subcommand, subcommand_class) + subcommands << subcommand.to_s + subcommand_class.subcommand_help subcommand + subcommand_classes[subcommand.to_s] = subcommand_class + + define_method(subcommand) do |*args| + args, opts = Bundler::Thor::Arguments.split(args) + invoke_args = [args, opts, {:invoked_via_subcommand => true, :class_options => options}] + invoke_args.unshift "help" if opts.delete("--help") || opts.delete("-h") + invoke subcommand_class, *invoke_args + end + subcommand_class.commands.each do |_meth, command| + command.ancestor_name = subcommand + end + end + alias_method :subtask, :subcommand + + # Extend check unknown options to accept a hash of conditions. + # + # === Parameters + # options: A hash containing :only and/or :except keys + def check_unknown_options!(options = {}) + @check_unknown_options ||= {} + options.each do |key, value| + if value + @check_unknown_options[key] = Array(value) + else + @check_unknown_options.delete(key) + end + end + @check_unknown_options + end + + # Overwrite check_unknown_options? to take subcommands and options into account. + def check_unknown_options?(config) #:nodoc: + options = check_unknown_options + return false unless options + + command = config[:current_command] + return true unless command + + name = command.name + + if subcommands.include?(name) + false + elsif options[:except] + !options[:except].include?(name.to_sym) + elsif options[:only] + options[:only].include?(name.to_sym) + else + true + end + end + + # Stop parsing of options as soon as an unknown option or a regular + # argument is encountered. All remaining arguments are passed to the command. + # This is useful if you have a command that can receive arbitrary additional + # options, and where those additional options should not be handled by + # Bundler::Thor. + # + # ==== Example + # + # To better understand how this is useful, let's consider a command that calls + # an external command. A user may want to pass arbitrary options and + # arguments to that command. The command itself also accepts some options, + # which should be handled by Bundler::Thor. + # + # class_option "verbose", :type => :boolean + # stop_on_unknown_option! :exec + # check_unknown_options! :except => :exec + # + # desc "exec", "Run a shell command" + # def exec(*args) + # puts "diagnostic output" if options[:verbose] + # Kernel.exec(*args) + # end + # + # Here +exec+ can be called with +--verbose+ to get diagnostic output, + # e.g.: + # + # $ thor exec --verbose echo foo + # diagnostic output + # foo + # + # But if +--verbose+ is given after +echo+, it is passed to +echo+ instead: + # + # $ thor exec echo --verbose foo + # --verbose foo + # + # ==== Parameters + # Symbol ...:: A list of commands that should be affected. + def stop_on_unknown_option!(*command_names) + @stop_on_unknown_option = stop_on_unknown_option | command_names + end + + def stop_on_unknown_option?(command) #:nodoc: + command && stop_on_unknown_option.include?(command.name.to_sym) + end + + # Disable the check for required options for the given commands. + # This is useful if you have a command that does not need the required options + # to work, like help. + # + # ==== Parameters + # Symbol ...:: A list of commands that should be affected. + def disable_required_check!(*command_names) + @disable_required_check = disable_required_check | command_names + end + + def disable_required_check?(command) #:nodoc: + command && disable_required_check.include?(command.name.to_sym) + end + + protected + + def stop_on_unknown_option #:nodoc: + @stop_on_unknown_option ||= [] + end + + # help command has the required check disabled by default. + def disable_required_check #:nodoc: + @disable_required_check ||= [:help] + end + + # The method responsible for dispatching given the args. + def dispatch(meth, given_args, given_opts, config) #:nodoc: # rubocop:disable MethodLength + meth ||= retrieve_command_name(given_args) + command = all_commands[normalize_command_name(meth)] + + if !command && config[:invoked_via_subcommand] + # We're a subcommand and our first argument didn't match any of our + # commands. So we put it back and call our default command. + given_args.unshift(meth) + command = all_commands[normalize_command_name(default_command)] + end + + if command + args, opts = Bundler::Thor::Options.split(given_args) + if stop_on_unknown_option?(command) && !args.empty? + # given_args starts with a non-option, so we treat everything as + # ordinary arguments + args.concat opts + opts.clear + end + else + args = given_args + opts = nil + command = dynamic_command_class.new(meth) + end + + opts = given_opts || opts || [] + config[:current_command] = command + config[:command_options] = command.options + + instance = new(args, opts, config) + yield instance if block_given? + args = instance.args + trailing = args[Range.new(arguments.size, -1)] + instance.invoke_command(command, trailing || []) + end + + # The banner for this class. You can customize it if you are invoking the + # thor class by another ways which is not the Bundler::Thor::Runner. It receives + # the command that is going to be invoked and a boolean which indicates if + # the namespace should be displayed as arguments. + # + def banner(command, namespace = nil, subcommand = false) + command.formatted_usage(self, $thor_runner, subcommand).split("\n").map do |formatted_usage| + "#{basename} #{formatted_usage}" + end.join("\n") + end + + def baseclass #:nodoc: + Bundler::Thor + end + + def dynamic_command_class #:nodoc: + Bundler::Thor::DynamicCommand + end + + def create_command(meth) #:nodoc: + @usage ||= nil + @desc ||= nil + @long_desc ||= nil + @hide ||= nil + + if @usage && @desc + base_class = @hide ? Bundler::Thor::HiddenCommand : Bundler::Thor::Command + commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options) + @usage, @desc, @long_desc, @method_options, @hide = nil + true + elsif all_commands[meth] || meth == "method_missing" + true + else + puts "[WARNING] Attempted to create command #{meth.inspect} without usage or description. " \ + "Call desc if you want this method to be available as command or declare it inside a " \ + "no_commands{} block. Invoked from #{caller[1].inspect}." + false + end + end + alias_method :create_task, :create_command + + def initialize_added #:nodoc: + class_options.merge!(method_options) + @method_options = nil + end + + # Retrieve the command name from given args. + def retrieve_command_name(args) #:nodoc: + meth = args.first.to_s unless args.empty? + args.shift if meth && (map[meth] || meth !~ /^\-/) + end + alias_method :retrieve_task_name, :retrieve_command_name + + # receives a (possibly nil) command name and returns a name that is in + # the commands hash. In addition to normalizing aliases, this logic + # will determine if a shortened command is an unambiguous substring of + # a command or alias. + # + # +normalize_command_name+ also converts names like +animal-prison+ + # into +animal_prison+. + def normalize_command_name(meth) #:nodoc: + return default_command.to_s.tr("-", "_") unless meth + + possibilities = find_command_possibilities(meth) + raise AmbiguousTaskError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]" if possibilities.size > 1 + + if possibilities.empty? + meth ||= default_command + elsif map[meth] + meth = map[meth] + else + meth = possibilities.first + end + + meth.to_s.tr("-", "_") # treat foo-bar as foo_bar + end + alias_method :normalize_task_name, :normalize_command_name + + # this is the logic that takes the command name passed in by the user + # and determines whether it is an unambiguous substrings of a command or + # alias name. + def find_command_possibilities(meth) + len = meth.to_s.length + possibilities = all_commands.merge(map).keys.select { |n| meth == n[0, len] }.sort + unique_possibilities = possibilities.map { |k| map[k] || k }.uniq + + if possibilities.include?(meth) + [meth] + elsif unique_possibilities.size == 1 + unique_possibilities + else + possibilities + end + end + alias_method :find_task_possibilities, :find_command_possibilities + + def subcommand_help(cmd) + desc "help [COMMAND]", "Describe subcommands or one specific subcommand" + class_eval " + def help(command = nil, subcommand = true); super; end +" + end + alias_method :subtask_help, :subcommand_help + end + + include Bundler::Thor::Base + + map HELP_MAPPINGS => :help + + desc "help [COMMAND]", "Describe available commands or one specific command" + def help(command = nil, subcommand = false) + if command + if self.class.subcommands.include? command + self.class.subcommand_classes[command].help(shell, true) + else + self.class.command_help(shell, command) + end + else + self.class.help(shell, subcommand) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions.rb new file mode 100644 index 0000000..de9b3b4 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions.rb @@ -0,0 +1,340 @@ +require_relative "actions/create_file" +require_relative "actions/create_link" +require_relative "actions/directory" +require_relative "actions/empty_directory" +require_relative "actions/file_manipulation" +require_relative "actions/inject_into_file" + +class Bundler::Thor + module Actions + attr_accessor :behavior + + def self.included(base) #:nodoc: + super(base) + base.extend ClassMethods + end + + module ClassMethods + # Hold source paths for one Bundler::Thor instance. source_paths_for_search is the + # method responsible to gather source_paths from this current class, + # inherited paths and the source root. + # + def source_paths + @_source_paths ||= [] + end + + # Stores and return the source root for this class + def source_root(path = nil) + @_source_root = path if path + @_source_root ||= nil + end + + # Returns the source paths in the following order: + # + # 1) This class source paths + # 2) Source root + # 3) Parents source paths + # + def source_paths_for_search + paths = [] + paths += source_paths + paths << source_root if source_root + paths += from_superclass(:source_paths, []) + paths + end + + # Add runtime options that help actions execution. + # + def add_runtime_options! + class_option :force, :type => :boolean, :aliases => "-f", :group => :runtime, + :desc => "Overwrite files that already exist" + + class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime, + :desc => "Run but do not make any changes" + + class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime, + :desc => "Suppress status output" + + class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime, + :desc => "Skip files that already exist" + end + end + + # Extends initializer to add more configuration options. + # + # ==== Configuration + # behavior:: The actions default behavior. Can be :invoke or :revoke. + # It also accepts :force, :skip and :pretend to set the behavior + # and the respective option. + # + # destination_root:: The root directory needed for some actions. + # + def initialize(args = [], options = {}, config = {}) + self.behavior = case config[:behavior].to_s + when "force", "skip" + _cleanup_options_and_set(options, config[:behavior]) + :invoke + when "revoke" + :revoke + else + :invoke + end + + super + self.destination_root = config[:destination_root] + end + + # Wraps an action object and call it accordingly to the thor class behavior. + # + def action(instance) #:nodoc: + if behavior == :revoke + instance.revoke! + else + instance.invoke! + end + end + + # Returns the root for this thor class (also aliased as destination root). + # + def destination_root + @destination_stack.last + end + + # Sets the root for this thor class. Relatives path are added to the + # directory where the script was invoked and expanded. + # + def destination_root=(root) + @destination_stack ||= [] + @destination_stack[0] = File.expand_path(root || "") + end + + # Returns the given path relative to the absolute root (ie, root where + # the script started). + # + def relative_to_original_destination_root(path, remove_dot = true) + root = @destination_stack[0] + if path.start_with?(root) && [File::SEPARATOR, File::ALT_SEPARATOR, nil, ''].include?(path[root.size..root.size]) + path = path.dup + path[0...root.size] = '.' + remove_dot ? (path[2..-1] || "") : path + else + path + end + end + + # Holds source paths in instance so they can be manipulated. + # + def source_paths + @source_paths ||= self.class.source_paths_for_search + end + + # Receives a file or directory and search for it in the source paths. + # + def find_in_source_paths(file) + possible_files = [file, file + TEMPLATE_EXTNAME] + relative_root = relative_to_original_destination_root(destination_root, false) + + source_paths.each do |source| + possible_files.each do |f| + source_file = File.expand_path(f, File.join(source, relative_root)) + return source_file if File.exist?(source_file) + end + end + + message = "Could not find #{file.inspect} in any of your source paths. ".dup + + unless self.class.source_root + message << "Please invoke #{self.class.name}.source_root(PATH) with the PATH containing your templates. " + end + + message << if source_paths.empty? + "Currently you have no source paths." + else + "Your current source paths are: \n#{source_paths.join("\n")}" + end + + raise Error, message + end + + # Do something in the root or on a provided subfolder. If a relative path + # is given it's referenced from the current root. The full path is yielded + # to the block you provide. The path is set back to the previous path when + # the method exits. + # + # Returns the value yielded by the block. + # + # ==== Parameters + # dir:: the directory to move to. + # config:: give :verbose => true to log and use padding. + # + def inside(dir = "", config = {}, &block) + verbose = config.fetch(:verbose, false) + pretend = options[:pretend] + + say_status :inside, dir, verbose + shell.padding += 1 if verbose + @destination_stack.push File.expand_path(dir, destination_root) + + # If the directory doesnt exist and we're not pretending + if !File.exist?(destination_root) && !pretend + require "fileutils" + FileUtils.mkdir_p(destination_root) + end + + result = nil + if pretend + # In pretend mode, just yield down to the block + result = block.arity == 1 ? yield(destination_root) : yield + else + require "fileutils" + FileUtils.cd(destination_root) { result = block.arity == 1 ? yield(destination_root) : yield } + end + + @destination_stack.pop + shell.padding -= 1 if verbose + result + end + + # Goes to the root and execute the given block. + # + def in_root + inside(@destination_stack.first) { yield } + end + + # Loads an external file and execute it in the instance binding. + # + # ==== Parameters + # path:: The path to the file to execute. Can be a web address or + # a relative path from the source root. + # + # ==== Examples + # + # apply "http://gist.github.com/103208" + # + # apply "recipes/jquery.rb" + # + def apply(path, config = {}) + verbose = config.fetch(:verbose, true) + is_uri = path =~ %r{^https?\://} + path = find_in_source_paths(path) unless is_uri + + say_status :apply, path, verbose + shell.padding += 1 if verbose + + contents = if is_uri + require "open-uri" + URI.open(path, "Accept" => "application/x-thor-template", &:read) + else + open(path, &:read) + end + + instance_eval(contents, path) + shell.padding -= 1 if verbose + end + + # Executes a command returning the contents of the command. + # + # ==== Parameters + # command:: the command to be executed. + # config:: give :verbose => false to not log the status, :capture => true to hide to output. Specify :with + # to append an executable to command execution. + # + # ==== Example + # + # inside('vendor') do + # run('ln -s ~/edge rails') + # end + # + def run(command, config = {}) + return unless behavior == :invoke + + destination = relative_to_original_destination_root(destination_root, false) + desc = "#{command} from #{destination.inspect}" + + if config[:with] + desc = "#{File.basename(config[:with].to_s)} #{desc}" + command = "#{config[:with]} #{command}" + end + + say_status :run, desc, config.fetch(:verbose, true) + + return if options[:pretend] + + env_splat = [config[:env]] if config[:env] + + if config[:capture] + require "open3" + result, status = Open3.capture2e(*env_splat, command.to_s) + success = status.success? + else + result = system(*env_splat, command.to_s) + success = result + end + + abort if !success && config.fetch(:abort_on_failure, self.class.exit_on_failure?) + + result + end + + # Executes a ruby script (taking into account WIN32 platform quirks). + # + # ==== Parameters + # command:: the command to be executed. + # config:: give :verbose => false to not log the status. + # + def run_ruby_script(command, config = {}) + return unless behavior == :invoke + run command, config.merge(:with => Bundler::Thor::Util.ruby_command) + end + + # Run a thor command. A hash of options can be given and it's converted to + # switches. + # + # ==== Parameters + # command:: the command to be invoked + # args:: arguments to the command + # config:: give :verbose => false to not log the status, :capture => true to hide to output. + # Other options are given as parameter to Bundler::Thor. + # + # + # ==== Examples + # + # thor :install, "http://gist.github.com/103208" + # #=> thor install http://gist.github.com/103208 + # + # thor :list, :all => true, :substring => 'rails' + # #=> thor list --all --substring=rails + # + def thor(command, *args) + config = args.last.is_a?(Hash) ? args.pop : {} + verbose = config.key?(:verbose) ? config.delete(:verbose) : true + pretend = config.key?(:pretend) ? config.delete(:pretend) : false + capture = config.key?(:capture) ? config.delete(:capture) : false + + args.unshift(command) + args.push Bundler::Thor::Options.to_switches(config) + command = args.join(" ").strip + + run command, :with => :thor, :verbose => verbose, :pretend => pretend, :capture => capture + end + + protected + + # Allow current root to be shared between invocations. + # + def _shared_configuration #:nodoc: + super.merge!(:destination_root => destination_root) + end + + def _cleanup_options_and_set(options, key) #:nodoc: + case options + when Array + %w(--force -f --skip -s).each { |i| options.delete(i) } + options << "--#{key}" + when Hash + [:force, :skip, "force", "skip"].each { |i| options.delete(i) } + options.merge!(key => true) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/create_file.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/create_file.rb new file mode 100644 index 0000000..330fc08 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/create_file.rb @@ -0,0 +1,104 @@ +require_relative "empty_directory" + +class Bundler::Thor + module Actions + # Create a new file relative to the destination root with the given data, + # which is the return value of a block or a data string. + # + # ==== Parameters + # destination:: the relative path to the destination root. + # data:: the data to append to the file. + # config:: give :verbose => false to not log the status. + # + # ==== Examples + # + # create_file "lib/fun_party.rb" do + # hostname = ask("What is the virtual hostname I should use?") + # "vhost.name = #{hostname}" + # end + # + # create_file "config/apache.conf", "your apache config" + # + def create_file(destination, *args, &block) + config = args.last.is_a?(Hash) ? args.pop : {} + data = args.first + action CreateFile.new(self, destination, block || data.to_s, config) + end + alias_method :add_file, :create_file + + # CreateFile is a subset of Template, which instead of rendering a file with + # ERB, it gets the content from the user. + # + class CreateFile < EmptyDirectory #:nodoc: + attr_reader :data + + def initialize(base, destination, data, config = {}) + @data = data + super(base, destination, config) + end + + # Checks if the content of the file at the destination is identical to the rendered result. + # + # ==== Returns + # Boolean:: true if it is identical, false otherwise. + # + def identical? + exists? && File.binread(destination) == render + end + + # Holds the content to be added to the file. + # + def render + @render ||= if data.is_a?(Proc) + data.call + else + data + end + end + + def invoke! + invoke_with_conflict_check do + require "fileutils" + FileUtils.mkdir_p(File.dirname(destination)) + File.open(destination, "wb") { |f| f.write render } + end + given_destination + end + + protected + + # Now on conflict we check if the file is identical or not. + # + def on_conflict_behavior(&block) + if identical? + say_status :identical, :blue + else + options = base.options.merge(config) + force_or_skip_or_conflict(options[:force], options[:skip], &block) + end + end + + # If force is true, run the action, otherwise check if it's not being + # skipped. If both are false, show the file_collision menu, if the menu + # returns true, force it, otherwise skip. + # + def force_or_skip_or_conflict(force, skip, &block) + if force + say_status :force, :yellow + yield unless pretend? + elsif skip + say_status :skip, :yellow + else + say_status :conflict, :red + force_or_skip_or_conflict(force_on_collision?, true, &block) + end + end + + # Shows the file collision menu to the user and gets the result. + # + def force_on_collision? + base.shell.file_collision(destination) { render } + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/create_link.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/create_link.rb new file mode 100644 index 0000000..fb76fcd --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/create_link.rb @@ -0,0 +1,61 @@ +require_relative "create_file" + +class Bundler::Thor + module Actions + # Create a new file relative to the destination root from the given source. + # + # ==== Parameters + # destination:: the relative path to the destination root. + # source:: the relative path to the source root. + # config:: give :verbose => false to not log the status. + # :: give :symbolic => false for hard link. + # + # ==== Examples + # + # create_link "config/apache.conf", "/etc/apache.conf" + # + def create_link(destination, *args) + config = args.last.is_a?(Hash) ? args.pop : {} + source = args.first + action CreateLink.new(self, destination, source, config) + end + alias_method :add_link, :create_link + + # CreateLink is a subset of CreateFile, which instead of taking a block of + # data, just takes a source string from the user. + # + class CreateLink < CreateFile #:nodoc: + attr_reader :data + + # Checks if the content of the file at the destination is identical to the rendered result. + # + # ==== Returns + # Boolean:: true if it is identical, false otherwise. + # + def identical? + source = File.expand_path(render, File.dirname(destination)) + exists? && File.identical?(source, destination) + end + + def invoke! + invoke_with_conflict_check do + require "fileutils" + FileUtils.mkdir_p(File.dirname(destination)) + # Create a symlink by default + config[:symbolic] = true if config[:symbolic].nil? + File.unlink(destination) if exists? + if config[:symbolic] + File.symlink(render, destination) + else + File.link(render, destination) + end + end + given_destination + end + + def exists? + super || File.symlink?(destination) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/directory.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/directory.rb new file mode 100644 index 0000000..d37327a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/directory.rb @@ -0,0 +1,108 @@ +require_relative "empty_directory" + +class Bundler::Thor + module Actions + # Copies recursively the files from source directory to root directory. + # If any of the files finishes with .tt, it's considered to be a template + # and is placed in the destination without the extension .tt. If any + # empty directory is found, it's copied and all .empty_directory files are + # ignored. If any file name is wrapped within % signs, the text within + # the % signs will be executed as a method and replaced with the returned + # value. Let's suppose a doc directory with the following files: + # + # doc/ + # components/.empty_directory + # README + # rdoc.rb.tt + # %app_name%.rb + # + # When invoked as: + # + # directory "doc" + # + # It will create a doc directory in the destination with the following + # files (assuming that the `app_name` method returns the value "blog"): + # + # doc/ + # components/ + # README + # rdoc.rb + # blog.rb + # + # Encoded path note: Since Bundler::Thor internals use Object#respond_to? to check if it can + # expand %something%, this `something` should be a public method in the class calling + # #directory. If a method is private, Bundler::Thor stack raises PrivateMethodEncodedError. + # + # ==== Parameters + # source:: the relative path to the source root. + # destination:: the relative path to the destination root. + # config:: give :verbose => false to not log the status. + # If :recursive => false, does not look for paths recursively. + # If :mode => :preserve, preserve the file mode from the source. + # If :exclude_pattern => /regexp/, prevents copying files that match that regexp. + # + # ==== Examples + # + # directory "doc" + # directory "doc", "docs", :recursive => false + # + def directory(source, *args, &block) + config = args.last.is_a?(Hash) ? args.pop : {} + destination = args.first || source + action Directory.new(self, source, destination || source, config, &block) + end + + class Directory < EmptyDirectory #:nodoc: + attr_reader :source + + def initialize(base, source, destination = nil, config = {}, &block) + @source = File.expand_path(Dir[Util.escape_globs(base.find_in_source_paths(source.to_s))].first) + @block = block + super(base, destination, {:recursive => true}.merge(config)) + end + + def invoke! + base.empty_directory given_destination, config + execute! + end + + def revoke! + execute! + end + + protected + + def execute! + lookup = Util.escape_globs(source) + lookup = config[:recursive] ? File.join(lookup, "**") : lookup + lookup = file_level_lookup(lookup) + + files(lookup).sort.each do |file_source| + next if File.directory?(file_source) + next if config[:exclude_pattern] && file_source.match(config[:exclude_pattern]) + file_destination = File.join(given_destination, file_source.gsub(source, ".")) + file_destination.gsub!("/./", "/") + + case file_source + when /\.empty_directory$/ + dirname = File.dirname(file_destination).gsub(%r{/\.$}, "") + next if dirname == given_destination + base.empty_directory(dirname, config) + when /#{TEMPLATE_EXTNAME}$/ + base.template(file_source, file_destination[0..-4], config, &@block) + else + base.copy_file(file_source, file_destination, config, &@block) + end + end + end + + def file_level_lookup(previous_lookup) + File.join(previous_lookup, "*") + end + + def files(lookup) + Dir.glob(lookup, File::FNM_DOTMATCH) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb new file mode 100644 index 0000000..284d92c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb @@ -0,0 +1,143 @@ +class Bundler::Thor + module Actions + # Creates an empty directory. + # + # ==== Parameters + # destination:: the relative path to the destination root. + # config:: give :verbose => false to not log the status. + # + # ==== Examples + # + # empty_directory "doc" + # + def empty_directory(destination, config = {}) + action EmptyDirectory.new(self, destination, config) + end + + # Class which holds create directory logic. This is the base class for + # other actions like create_file and directory. + # + # This implementation is based in Templater actions, created by Jonas Nicklas + # and Michael S. Klishin under MIT LICENSE. + # + class EmptyDirectory #:nodoc: + attr_reader :base, :destination, :given_destination, :relative_destination, :config + + # Initializes given the source and destination. + # + # ==== Parameters + # base:: A Bundler::Thor::Base instance + # source:: Relative path to the source of this file + # destination:: Relative path to the destination of this file + # config:: give :verbose => false to not log the status. + # + def initialize(base, destination, config = {}) + @base = base + @config = {:verbose => true}.merge(config) + self.destination = destination + end + + # Checks if the destination file already exists. + # + # ==== Returns + # Boolean:: true if the file exists, false otherwise. + # + def exists? + ::File.exist?(destination) + end + + def invoke! + invoke_with_conflict_check do + require "fileutils" + ::FileUtils.mkdir_p(destination) + end + end + + def revoke! + say_status :remove, :red + require "fileutils" + ::FileUtils.rm_rf(destination) if !pretend? && exists? + given_destination + end + + protected + + # Shortcut for pretend. + # + def pretend? + base.options[:pretend] + end + + # Sets the absolute destination value from a relative destination value. + # It also stores the given and relative destination. Let's suppose our + # script is being executed on "dest", it sets the destination root to + # "dest". The destination, given_destination and relative_destination + # are related in the following way: + # + # inside "bar" do + # empty_directory "baz" + # end + # + # destination #=> dest/bar/baz + # relative_destination #=> bar/baz + # given_destination #=> baz + # + def destination=(destination) + return unless destination + @given_destination = convert_encoded_instructions(destination.to_s) + @destination = ::File.expand_path(@given_destination, base.destination_root) + @relative_destination = base.relative_to_original_destination_root(@destination) + end + + # Filenames in the encoded form are converted. If you have a file: + # + # %file_name%.rb + # + # It calls #file_name from the base and replaces %-string with the + # return value (should be String) of #file_name: + # + # user.rb + # + # The method referenced can be either public or private. + # + def convert_encoded_instructions(filename) + filename.gsub(/%(.*?)%/) do |initial_string| + method = $1.strip + base.respond_to?(method, true) ? base.send(method) : initial_string + end + end + + # Receives a hash of options and just execute the block if some + # conditions are met. + # + def invoke_with_conflict_check(&block) + if exists? + on_conflict_behavior(&block) + else + yield unless pretend? + say_status :create, :green + end + + destination + rescue Errno::EISDIR, Errno::EEXIST + on_file_clash_behavior + end + + def on_file_clash_behavior + say_status :file_clash, :red + end + + # What to do when the destination file already exists. + # + def on_conflict_behavior + say_status :exist, :blue + end + + # Shortcut to say_status shell method. + # + def say_status(status, color) + base.shell.say_status status, relative_destination, color if config[:verbose] + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb new file mode 100644 index 0000000..bf2a737 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb @@ -0,0 +1,375 @@ +require "erb" + +class Bundler::Thor + module Actions + # Copies the file from the relative source to the relative destination. If + # the destination is not given it's assumed to be equal to the source. + # + # ==== Parameters + # source:: the relative path to the source root. + # destination:: the relative path to the destination root. + # config:: give :verbose => false to not log the status, and + # :mode => :preserve, to preserve the file mode from the source. + + # + # ==== Examples + # + # copy_file "README", "doc/README" + # + # copy_file "doc/README" + # + def copy_file(source, *args, &block) + config = args.last.is_a?(Hash) ? args.pop : {} + destination = args.first || source + source = File.expand_path(find_in_source_paths(source.to_s)) + + resulting_destination = create_file destination, nil, config do + content = File.binread(source) + content = yield(content) if block + content + end + if config[:mode] == :preserve + mode = File.stat(source).mode + chmod(resulting_destination, mode, config) + end + end + + # Links the file from the relative source to the relative destination. If + # the destination is not given it's assumed to be equal to the source. + # + # ==== Parameters + # source:: the relative path to the source root. + # destination:: the relative path to the destination root. + # config:: give :verbose => false to not log the status. + # + # ==== Examples + # + # link_file "README", "doc/README" + # + # link_file "doc/README" + # + def link_file(source, *args) + config = args.last.is_a?(Hash) ? args.pop : {} + destination = args.first || source + source = File.expand_path(find_in_source_paths(source.to_s)) + + create_link destination, source, config + end + + # Gets the content at the given address and places it at the given relative + # destination. If a block is given instead of destination, the content of + # the url is yielded and used as location. + # + # +get+ relies on open-uri, so passing application user input would provide + # a command injection attack vector. + # + # ==== Parameters + # source:: the address of the given content. + # destination:: the relative path to the destination root. + # config:: give :verbose => false to not log the status. + # + # ==== Examples + # + # get "http://gist.github.com/103208", "doc/README" + # + # get "http://gist.github.com/103208" do |content| + # content.split("\n").first + # end + # + def get(source, *args, &block) + config = args.last.is_a?(Hash) ? args.pop : {} + destination = args.first + + render = if source =~ %r{^https?\://} + require "open-uri" + URI.send(:open, source) { |input| input.binmode.read } + else + source = File.expand_path(find_in_source_paths(source.to_s)) + open(source) { |input| input.binmode.read } + end + + destination ||= if block_given? + block.arity == 1 ? yield(render) : yield + else + File.basename(source) + end + + create_file destination, render, config + end + + # Gets an ERB template at the relative source, executes it and makes a copy + # at the relative destination. If the destination is not given it's assumed + # to be equal to the source removing .tt from the filename. + # + # ==== Parameters + # source:: the relative path to the source root. + # destination:: the relative path to the destination root. + # config:: give :verbose => false to not log the status. + # + # ==== Examples + # + # template "README", "doc/README" + # + # template "doc/README" + # + def template(source, *args, &block) + config = args.last.is_a?(Hash) ? args.pop : {} + destination = args.first || source.sub(/#{TEMPLATE_EXTNAME}$/, "") + + source = File.expand_path(find_in_source_paths(source.to_s)) + context = config.delete(:context) || instance_eval("binding") + + create_file destination, nil, config do + match = ERB.version.match(/(\d+\.\d+\.\d+)/) + capturable_erb = if match && match[1] >= "2.2.0" # Ruby 2.6+ + CapturableERB.new(::File.binread(source), :trim_mode => "-", :eoutvar => "@output_buffer") + else + CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer") + end + content = capturable_erb.tap do |erb| + erb.filename = source + end.result(context) + content = yield(content) if block + content + end + end + + # Changes the mode of the given file or directory. + # + # ==== Parameters + # mode:: the file mode + # path:: the name of the file to change mode + # config:: give :verbose => false to not log the status. + # + # ==== Example + # + # chmod "script/server", 0755 + # + def chmod(path, mode, config = {}) + return unless behavior == :invoke + path = File.expand_path(path, destination_root) + say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true) + unless options[:pretend] + require "fileutils" + FileUtils.chmod_R(mode, path) + end + end + + # Prepend text to a file. Since it depends on insert_into_file, it's reversible. + # + # ==== Parameters + # path:: path of the file to be changed + # data:: the data to prepend to the file, can be also given as a block. + # config:: give :verbose => false to not log the status. + # + # ==== Example + # + # prepend_to_file 'config/environments/test.rb', 'config.gem "rspec"' + # + # prepend_to_file 'config/environments/test.rb' do + # 'config.gem "rspec"' + # end + # + def prepend_to_file(path, *args, &block) + config = args.last.is_a?(Hash) ? args.pop : {} + config[:after] = /\A/ + insert_into_file(path, *(args << config), &block) + end + alias_method :prepend_file, :prepend_to_file + + # Append text to a file. Since it depends on insert_into_file, it's reversible. + # + # ==== Parameters + # path:: path of the file to be changed + # data:: the data to append to the file, can be also given as a block. + # config:: give :verbose => false to not log the status. + # + # ==== Example + # + # append_to_file 'config/environments/test.rb', 'config.gem "rspec"' + # + # append_to_file 'config/environments/test.rb' do + # 'config.gem "rspec"' + # end + # + def append_to_file(path, *args, &block) + config = args.last.is_a?(Hash) ? args.pop : {} + config[:before] = /\z/ + insert_into_file(path, *(args << config), &block) + end + alias_method :append_file, :append_to_file + + # Injects text right after the class definition. Since it depends on + # insert_into_file, it's reversible. + # + # ==== Parameters + # path:: path of the file to be changed + # klass:: the class to be manipulated + # data:: the data to append to the class, can be also given as a block. + # config:: give :verbose => false to not log the status. + # + # ==== Examples + # + # inject_into_class "app/controllers/application_controller.rb", "ApplicationController", " filter_parameter :password\n" + # + # inject_into_class "app/controllers/application_controller.rb", "ApplicationController" do + # " filter_parameter :password\n" + # end + # + def inject_into_class(path, klass, *args, &block) + config = args.last.is_a?(Hash) ? args.pop : {} + config[:after] = /class #{klass}\n|class #{klass} .*\n/ + insert_into_file(path, *(args << config), &block) + end + + # Injects text right after the module definition. Since it depends on + # insert_into_file, it's reversible. + # + # ==== Parameters + # path:: path of the file to be changed + # module_name:: the module to be manipulated + # data:: the data to append to the class, can be also given as a block. + # config:: give :verbose => false to not log the status. + # + # ==== Examples + # + # inject_into_module "app/helpers/application_helper.rb", "ApplicationHelper", " def help; 'help'; end\n" + # + # inject_into_module "app/helpers/application_helper.rb", "ApplicationHelper" do + # " def help; 'help'; end\n" + # end + # + def inject_into_module(path, module_name, *args, &block) + config = args.last.is_a?(Hash) ? args.pop : {} + config[:after] = /module #{module_name}\n|module #{module_name} .*\n/ + insert_into_file(path, *(args << config), &block) + end + + # Run a regular expression replacement on a file. + # + # ==== Parameters + # path:: path of the file to be changed + # flag:: the regexp or string to be replaced + # replacement:: the replacement, can be also given as a block + # config:: give :verbose => false to not log the status, and + # :force => true, to force the replacement regardles of runner behavior. + # + # ==== Example + # + # gsub_file 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1' + # + # gsub_file 'README', /rake/, :green do |match| + # match << " no more. Use thor!" + # end + # + def gsub_file(path, flag, *args, &block) + config = args.last.is_a?(Hash) ? args.pop : {} + + return unless behavior == :invoke || config.fetch(:force, false) + + path = File.expand_path(path, destination_root) + say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true) + + unless options[:pretend] + content = File.binread(path) + content.gsub!(flag, *args, &block) + File.open(path, "wb") { |file| file.write(content) } + end + end + + # Uncomment all lines matching a given regex. It will leave the space + # which existed before the comment hash in tact but will remove any spacing + # between the comment hash and the beginning of the line. + # + # ==== Parameters + # path:: path of the file to be changed + # flag:: the regexp or string used to decide which lines to uncomment + # config:: give :verbose => false to not log the status. + # + # ==== Example + # + # uncomment_lines 'config/initializers/session_store.rb', /active_record/ + # + def uncomment_lines(path, flag, *args) + flag = flag.respond_to?(:source) ? flag.source : flag + + gsub_file(path, /^(\s*)#[[:blank:]]*(.*#{flag})/, '\1\2', *args) + end + + # Comment all lines matching a given regex. It will leave the space + # which existed before the beginning of the line in tact and will insert + # a single space after the comment hash. + # + # ==== Parameters + # path:: path of the file to be changed + # flag:: the regexp or string used to decide which lines to comment + # config:: give :verbose => false to not log the status. + # + # ==== Example + # + # comment_lines 'config/initializers/session_store.rb', /cookie_store/ + # + def comment_lines(path, flag, *args) + flag = flag.respond_to?(:source) ? flag.source : flag + + gsub_file(path, /^(\s*)([^#\n]*#{flag})/, '\1# \2', *args) + end + + # Removes a file at the given location. + # + # ==== Parameters + # path:: path of the file to be changed + # config:: give :verbose => false to not log the status. + # + # ==== Example + # + # remove_file 'README' + # remove_file 'app/controllers/application_controller.rb' + # + def remove_file(path, config = {}) + return unless behavior == :invoke + path = File.expand_path(path, destination_root) + + say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true) + if !options[:pretend] && (File.exist?(path) || File.symlink?(path)) + require "fileutils" + ::FileUtils.rm_rf(path) + end + end + alias_method :remove_dir, :remove_file + + attr_accessor :output_buffer + private :output_buffer, :output_buffer= + + private + + def concat(string) + @output_buffer.concat(string) + end + + def capture(*args) + with_output_buffer { yield(*args) } + end + + def with_output_buffer(buf = "".dup) #:nodoc: + raise ArgumentError, "Buffer can not be a frozen object" if buf.frozen? + old_buffer = output_buffer + self.output_buffer = buf + yield + output_buffer + ensure + self.output_buffer = old_buffer + end + + # Bundler::Thor::Actions#capture depends on what kind of buffer is used in ERB. + # Thus CapturableERB fixes ERB to use String buffer. + class CapturableERB < ERB + def set_eoutvar(compiler, eoutvar = "_erbout") + compiler.put_cmd = "#{eoutvar}.concat" + compiler.insert_cmd = "#{eoutvar}.concat" + compiler.pre_cmd = ["#{eoutvar} = ''.dup"] + compiler.post_cmd = [eoutvar] + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb new file mode 100644 index 0000000..bf01330 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb @@ -0,0 +1,119 @@ +require_relative "empty_directory" + +class Bundler::Thor + module Actions + # Injects the given content into a file. Different from gsub_file, this + # method is reversible. + # + # ==== Parameters + # destination:: Relative path to the destination root + # data:: Data to add to the file. Can be given as a block. + # config:: give :verbose => false to not log the status and the flag + # for injection (:after or :before) or :force => true for + # insert two or more times the same content. + # + # ==== Examples + # + # insert_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n" + # + # insert_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do + # gems = ask "Which gems would you like to add?" + # gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n") + # end + # + WARNINGS = { unchanged_no_flag: 'File unchanged! The supplied flag value not found!' } + + def insert_into_file(destination, *args, &block) + data = block_given? ? block : args.shift + + config = args.shift || {} + config[:after] = /\z/ unless config.key?(:before) || config.key?(:after) + + action InjectIntoFile.new(self, destination, data, config) + end + alias_method :inject_into_file, :insert_into_file + + class InjectIntoFile < EmptyDirectory #:nodoc: + attr_reader :replacement, :flag, :behavior + + def initialize(base, destination, data, config) + super(base, destination, {:verbose => true}.merge(config)) + + @behavior, @flag = if @config.key?(:after) + [:after, @config.delete(:after)] + else + [:before, @config.delete(:before)] + end + + @replacement = data.is_a?(Proc) ? data.call : data + @flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp) + end + + def invoke! + content = if @behavior == :after + '\0' + replacement + else + replacement + '\0' + end + + if exists? + if replace!(/#{flag}/, content, config[:force]) + say_status(:invoke) + else + say_status(:unchanged, warning: WARNINGS[:unchanged_no_flag], color: :red) + end + else + unless pretend? + raise Bundler::Thor::Error, "The file #{ destination } does not appear to exist" + end + end + end + + def revoke! + say_status :revoke + + regexp = if @behavior == :after + content = '\1\2' + /(#{flag})(.*)(#{Regexp.escape(replacement)})/m + else + content = '\2\3' + /(#{Regexp.escape(replacement)})(.*)(#{flag})/m + end + + replace!(regexp, content, true) + end + + protected + + def say_status(behavior, warning: nil, color: nil) + status = if behavior == :invoke + if flag == /\A/ + :prepend + elsif flag == /\z/ + :append + else + :insert + end + elsif warning + warning + else + :subtract + end + + super(status, (color || config[:verbose])) + end + + # Adds the content to the file. + # + def replace!(regexp, string, force) + content = File.read(destination) + if force || !content.include?(replacement) + success = content.gsub!(regexp, string) + + File.open(destination, "wb") { |file| file.write(content) } unless pretend? + success + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/base.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/base.rb new file mode 100644 index 0000000..8487f95 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/base.rb @@ -0,0 +1,699 @@ +require_relative "command" +require_relative "core_ext/hash_with_indifferent_access" +require_relative "error" +require_relative "invocation" +require_relative "nested_context" +require_relative "parser" +require_relative "shell" +require_relative "line_editor" +require_relative "util" + +class Bundler::Thor + autoload :Actions, File.expand_path("actions", __dir__) + autoload :RakeCompat, File.expand_path("rake_compat", __dir__) + autoload :Group, File.expand_path("group", __dir__) + + # Shortcuts for help. + HELP_MAPPINGS = %w(-h -? --help -D) + + # Bundler::Thor methods that should not be overwritten by the user. + THOR_RESERVED_WORDS = %w(invoke shell options behavior root destination_root relative_root + action add_file create_file in_root inside run run_ruby_script) + + TEMPLATE_EXTNAME = ".tt" + + class << self + def deprecation_warning(message) #:nodoc: + unless ENV['THOR_SILENCE_DEPRECATION'] + warn "Deprecation warning: #{message}\n" + + 'You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.' + end + end + end + + module Base + attr_accessor :options, :parent_options, :args + + # It receives arguments in an Array and two hashes, one for options and + # other for configuration. + # + # Notice that it does not check if all required arguments were supplied. + # It should be done by the parser. + # + # ==== Parameters + # args:: An array of objects. The objects are applied to their + # respective accessors declared with argument. + # + # options:: An options hash that will be available as self.options. + # The hash given is converted to a hash with indifferent + # access, magic predicates (options.skip?) and then frozen. + # + # config:: Configuration for this Bundler::Thor class. + # + def initialize(args = [], local_options = {}, config = {}) + parse_options = self.class.class_options + + # The start method splits inbound arguments at the first argument + # that looks like an option (starts with - or --). It then calls + # new, passing in the two halves of the arguments Array as the + # first two parameters. + + command_options = config.delete(:command_options) # hook for start + parse_options = parse_options.merge(command_options) if command_options + if local_options.is_a?(Array) + array_options = local_options + hash_options = {} + else + # Handle the case where the class was explicitly instantiated + # with pre-parsed options. + array_options = [] + hash_options = local_options + end + + # Let Bundler::Thor::Options parse the options first, so it can remove + # declared options from the array. This will leave us with + # a list of arguments that weren't declared. + stop_on_unknown = self.class.stop_on_unknown_option? config[:current_command] + disable_required_check = self.class.disable_required_check? config[:current_command] + opts = Bundler::Thor::Options.new(parse_options, hash_options, stop_on_unknown, disable_required_check) + self.options = opts.parse(array_options) + self.options = config[:class_options].merge(options) if config[:class_options] + + # If unknown options are disallowed, make sure that none of the + # remaining arguments looks like an option. + opts.check_unknown! if self.class.check_unknown_options?(config) + + # Add the remaining arguments from the options parser to the + # arguments passed in to initialize. Then remove any positional + # arguments declared using #argument (this is primarily used + # by Bundler::Thor::Group). Tis will leave us with the remaining + # positional arguments. + to_parse = args + to_parse += opts.remaining unless self.class.strict_args_position?(config) + + thor_args = Bundler::Thor::Arguments.new(self.class.arguments) + thor_args.parse(to_parse).each { |k, v| __send__("#{k}=", v) } + @args = thor_args.remaining + end + + class << self + def included(base) #:nodoc: + super(base) + base.extend ClassMethods + base.send :include, Invocation + base.send :include, Shell + end + + # Returns the classes that inherits from Bundler::Thor or Bundler::Thor::Group. + # + # ==== Returns + # Array[Class] + # + def subclasses + @subclasses ||= [] + end + + # Returns the files where the subclasses are kept. + # + # ==== Returns + # Hash[path => Class] + # + def subclass_files + @subclass_files ||= Hash.new { |h, k| h[k] = [] } + end + + # Whenever a class inherits from Bundler::Thor or Bundler::Thor::Group, we should track the + # class and the file on Bundler::Thor::Base. This is the method responsible for it. + # + def register_klass_file(klass) #:nodoc: + file = caller[1].match(/(.*):\d+/)[1] + Bundler::Thor::Base.subclasses << klass unless Bundler::Thor::Base.subclasses.include?(klass) + + file_subclasses = Bundler::Thor::Base.subclass_files[File.expand_path(file)] + file_subclasses << klass unless file_subclasses.include?(klass) + end + end + + module ClassMethods + def attr_reader(*) #:nodoc: + no_commands { super } + end + + def attr_writer(*) #:nodoc: + no_commands { super } + end + + def attr_accessor(*) #:nodoc: + no_commands { super } + end + + # If you want to raise an error for unknown options, call check_unknown_options! + # This is disabled by default to allow dynamic invocations. + def check_unknown_options! + @check_unknown_options = true + end + + def check_unknown_options #:nodoc: + @check_unknown_options ||= from_superclass(:check_unknown_options, false) + end + + def check_unknown_options?(config) #:nodoc: + !!check_unknown_options + end + + # If you want to raise an error when the default value of an option does not match + # the type call check_default_type! + # This will be the default; for compatibility a deprecation warning is issued if necessary. + def check_default_type! + @check_default_type = true + end + + # If you want to use defaults that don't match the type of an option, + # either specify `check_default_type: false` or call `allow_incompatible_default_type!` + def allow_incompatible_default_type! + @check_default_type = false + end + + def check_default_type #:nodoc: + @check_default_type = from_superclass(:check_default_type, nil) unless defined?(@check_default_type) + @check_default_type + end + + # If true, option parsing is suspended as soon as an unknown option or a + # regular argument is encountered. All remaining arguments are passed to + # the command as regular arguments. + def stop_on_unknown_option?(command_name) #:nodoc: + false + end + + # If true, option set will not suspend the execution of the command when + # a required option is not provided. + def disable_required_check?(command_name) #:nodoc: + false + end + + # If you want only strict string args (useful when cascading thor classes), + # call strict_args_position! This is disabled by default to allow dynamic + # invocations. + def strict_args_position! + @strict_args_position = true + end + + def strict_args_position #:nodoc: + @strict_args_position ||= from_superclass(:strict_args_position, false) + end + + def strict_args_position?(config) #:nodoc: + !!strict_args_position + end + + # Adds an argument to the class and creates an attr_accessor for it. + # + # Arguments are different from options in several aspects. The first one + # is how they are parsed from the command line, arguments are retrieved + # from position: + # + # thor command NAME + # + # Instead of: + # + # thor command --name=NAME + # + # Besides, arguments are used inside your code as an accessor (self.argument), + # while options are all kept in a hash (self.options). + # + # Finally, arguments cannot have type :default or :boolean but can be + # optional (supplying :optional => :true or :required => false), although + # you cannot have a required argument after a non-required argument. If you + # try it, an error is raised. + # + # ==== Parameters + # name:: The name of the argument. + # options:: Described below. + # + # ==== Options + # :desc - Description for the argument. + # :required - If the argument is required or not. + # :optional - If the argument is optional or not. + # :type - The type of the argument, can be :string, :hash, :array, :numeric. + # :default - Default value for this argument. It cannot be required and have default values. + # :banner - String to show on usage notes. + # + # ==== Errors + # ArgumentError:: Raised if you supply a required argument after a non required one. + # + def argument(name, options = {}) + is_thor_reserved_word?(name, :argument) + no_commands { attr_accessor name } + + required = if options.key?(:optional) + !options[:optional] + elsif options.key?(:required) + options[:required] + else + options[:default].nil? + end + + remove_argument name + + if required + arguments.each do |argument| + next if argument.required? + raise ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " \ + "the non-required argument #{argument.human_name.inspect}." + end + end + + options[:required] = required + + arguments << Bundler::Thor::Argument.new(name, options) + end + + # Returns this class arguments, looking up in the ancestors chain. + # + # ==== Returns + # Array[Bundler::Thor::Argument] + # + def arguments + @arguments ||= from_superclass(:arguments, []) + end + + # Adds a bunch of options to the set of class options. + # + # class_options :foo => false, :bar => :required, :baz => :string + # + # If you prefer more detailed declaration, check class_option. + # + # ==== Parameters + # Hash[Symbol => Object] + # + def class_options(options = nil) + @class_options ||= from_superclass(:class_options, {}) + build_options(options, @class_options) if options + @class_options + end + + # Adds an option to the set of class options + # + # ==== Parameters + # name:: The name of the argument. + # options:: Described below. + # + # ==== Options + # :desc:: -- Description for the argument. + # :required:: -- If the argument is required or not. + # :default:: -- Default value for this argument. + # :group:: -- The group for this options. Use by class options to output options in different levels. + # :aliases:: -- Aliases for this option. Note: Bundler::Thor follows a convention of one-dash-one-letter options. Thus aliases like "-something" wouldn't be parsed; use either "\--something" or "-s" instead. + # :type:: -- The type of the argument, can be :string, :hash, :array, :numeric or :boolean. + # :banner:: -- String to show on usage notes. + # :hide:: -- If you want to hide this option from the help. + # + def class_option(name, options = {}) + build_option(name, options, class_options) + end + + # Removes a previous defined argument. If :undefine is given, undefine + # accessors as well. + # + # ==== Parameters + # names:: Arguments to be removed + # + # ==== Examples + # + # remove_argument :foo + # remove_argument :foo, :bar, :baz, :undefine => true + # + def remove_argument(*names) + options = names.last.is_a?(Hash) ? names.pop : {} + + names.each do |name| + arguments.delete_if { |a| a.name == name.to_s } + undef_method name, "#{name}=" if options[:undefine] + end + end + + # Removes a previous defined class option. + # + # ==== Parameters + # names:: Class options to be removed + # + # ==== Examples + # + # remove_class_option :foo + # remove_class_option :foo, :bar, :baz + # + def remove_class_option(*names) + names.each do |name| + class_options.delete(name) + end + end + + # Defines the group. This is used when thor list is invoked so you can specify + # that only commands from a pre-defined group will be shown. Defaults to standard. + # + # ==== Parameters + # name + # + def group(name = nil) + if name + @group = name.to_s + else + @group ||= from_superclass(:group, "standard") + end + end + + # Returns the commands for this Bundler::Thor class. + # + # ==== Returns + # Hash:: An ordered hash with commands names as keys and Bundler::Thor::Command + # objects as values. + # + def commands + @commands ||= Hash.new + end + alias_method :tasks, :commands + + # Returns the commands for this Bundler::Thor class and all subclasses. + # + # ==== Returns + # Hash:: An ordered hash with commands names as keys and Bundler::Thor::Command + # objects as values. + # + def all_commands + @all_commands ||= from_superclass(:all_commands, Hash.new) + @all_commands.merge!(commands) + end + alias_method :all_tasks, :all_commands + + # Removes a given command from this Bundler::Thor class. This is usually done if you + # are inheriting from another class and don't want it to be available + # anymore. + # + # By default it only remove the mapping to the command. But you can supply + # :undefine => true to undefine the method from the class as well. + # + # ==== Parameters + # name:: The name of the command to be removed + # options:: You can give :undefine => true if you want commands the method + # to be undefined from the class as well. + # + def remove_command(*names) + options = names.last.is_a?(Hash) ? names.pop : {} + + names.each do |name| + commands.delete(name.to_s) + all_commands.delete(name.to_s) + undef_method name if options[:undefine] + end + end + alias_method :remove_task, :remove_command + + # All methods defined inside the given block are not added as commands. + # + # So you can do: + # + # class MyScript < Bundler::Thor + # no_commands do + # def this_is_not_a_command + # end + # end + # end + # + # You can also add the method and remove it from the command list: + # + # class MyScript < Bundler::Thor + # def this_is_not_a_command + # end + # remove_command :this_is_not_a_command + # end + # + def no_commands(&block) + no_commands_context.enter(&block) + end + + alias_method :no_tasks, :no_commands + + def no_commands_context + @no_commands_context ||= NestedContext.new + end + + def no_commands? + no_commands_context.entered? + end + + # Sets the namespace for the Bundler::Thor or Bundler::Thor::Group class. By default the + # namespace is retrieved from the class name. If your Bundler::Thor class is named + # Scripts::MyScript, the help method, for example, will be called as: + # + # thor scripts:my_script -h + # + # If you change the namespace: + # + # namespace :my_scripts + # + # You change how your commands are invoked: + # + # thor my_scripts -h + # + # Finally, if you change your namespace to default: + # + # namespace :default + # + # Your commands can be invoked with a shortcut. Instead of: + # + # thor :my_command + # + def namespace(name = nil) + if name + @namespace = name.to_s + else + @namespace ||= Bundler::Thor::Util.namespace_from_thor_class(self) + end + end + + # Parses the command and options from the given args, instantiate the class + # and invoke the command. This method is used when the arguments must be parsed + # from an array. If you are inside Ruby and want to use a Bundler::Thor class, you + # can simply initialize it: + # + # script = MyScript.new(args, options, config) + # script.invoke(:command, first_arg, second_arg, third_arg) + # + def start(given_args = ARGV, config = {}) + config[:shell] ||= Bundler::Thor::Base.shell.new + dispatch(nil, given_args.dup, nil, config) + rescue Bundler::Thor::Error => e + config[:debug] || ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message) + exit(false) if exit_on_failure? + rescue Errno::EPIPE + # This happens if a thor command is piped to something like `head`, + # which closes the pipe when it's done reading. This will also + # mean that if the pipe is closed, further unnecessary + # computation will not occur. + exit(true) + end + + # Allows to use private methods from parent in child classes as commands. + # + # ==== Parameters + # names:: Method names to be used as commands + # + # ==== Examples + # + # public_command :foo + # public_command :foo, :bar, :baz + # + def public_command(*names) + names.each do |name| + class_eval "def #{name}(*); super end" + end + end + alias_method :public_task, :public_command + + def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc: + raise UndefinedCommandError.new(command, all_commands.keys, (namespace if has_namespace)) + end + alias_method :handle_no_task_error, :handle_no_command_error + + def handle_argument_error(command, error, args, arity) #:nodoc: + name = [command.ancestor_name, command.name].compact.join(" ") + msg = "ERROR: \"#{basename} #{name}\" was called with ".dup + msg << "no arguments" if args.empty? + msg << "arguments " << args.inspect unless args.empty? + msg << "\nUsage: \"#{banner(command).split("\n").join("\"\n \"")}\"" + raise InvocationError, msg + end + + # A flag that makes the process exit with status 1 if any error happens. + def exit_on_failure? + Bundler::Thor.deprecation_warning "Bundler::Thor exit with status 0 on errors. To keep this behavior, you must define `exit_on_failure?` in `#{self.name}`" + false + end + + protected + + # Prints the class options per group. If an option does not belong to + # any group, it's printed as Class option. + # + def class_options_help(shell, groups = {}) #:nodoc: + # Group options by group + class_options.each do |_, value| + groups[value.group] ||= [] + groups[value.group] << value + end + + # Deal with default group + global_options = groups.delete(nil) || [] + print_options(shell, global_options) + + # Print all others + groups.each do |group_name, options| + print_options(shell, options, group_name) + end + end + + # Receives a set of options and print them. + def print_options(shell, options, group_name = nil) + return if options.empty? + + list = [] + padding = options.map { |o| o.aliases.size }.max.to_i * 4 + + options.each do |option| + next if option.hide + item = [option.usage(padding)] + item.push(option.description ? "# #{option.description}" : "") + + list << item + list << ["", "# Default: #{option.default}"] if option.show_default? + list << ["", "# Possible values: #{option.enum.join(', ')}"] if option.enum + end + + shell.say(group_name ? "#{group_name} options:" : "Options:") + shell.print_table(list, :indent => 2) + shell.say "" + end + + # Raises an error if the word given is a Bundler::Thor reserved word. + def is_thor_reserved_word?(word, type) #:nodoc: + return false unless THOR_RESERVED_WORDS.include?(word.to_s) + raise "#{word.inspect} is a Bundler::Thor reserved word and cannot be defined as #{type}" + end + + # Build an option and adds it to the given scope. + # + # ==== Parameters + # name:: The name of the argument. + # options:: Described in both class_option and method_option. + # scope:: Options hash that is being built up + def build_option(name, options, scope) #:nodoc: + scope[name] = Bundler::Thor::Option.new(name, {:check_default_type => check_default_type}.merge!(options)) + end + + # Receives a hash of options, parse them and add to the scope. This is a + # fast way to set a bunch of options: + # + # build_options :foo => true, :bar => :required, :baz => :string + # + # ==== Parameters + # Hash[Symbol => Object] + def build_options(options, scope) #:nodoc: + options.each do |key, value| + scope[key] = Bundler::Thor::Option.parse(key, value) + end + end + + # Finds a command with the given name. If the command belongs to the current + # class, just return it, otherwise dup it and add the fresh copy to the + # current command hash. + def find_and_refresh_command(name) #:nodoc: + if commands[name.to_s] + commands[name.to_s] + elsif command = all_commands[name.to_s] # rubocop:disable AssignmentInCondition + commands[name.to_s] = command.clone + else + raise ArgumentError, "You supplied :for => #{name.inspect}, but the command #{name.inspect} could not be found." + end + end + alias_method :find_and_refresh_task, :find_and_refresh_command + + # Everytime someone inherits from a Bundler::Thor class, register the klass + # and file into baseclass. + def inherited(klass) + super(klass) + Bundler::Thor::Base.register_klass_file(klass) + klass.instance_variable_set(:@no_commands, 0) + end + + # Fire this callback whenever a method is added. Added methods are + # tracked as commands by invoking the create_command method. + def method_added(meth) + super(meth) + meth = meth.to_s + + if meth == "initialize" + initialize_added + return + end + + # Return if it's not a public instance method + return unless public_method_defined?(meth.to_sym) + + return if no_commands? || !create_command(meth) + + is_thor_reserved_word?(meth, :command) + Bundler::Thor::Base.register_klass_file(self) + end + + # Retrieves a value from superclass. If it reaches the baseclass, + # returns default. + def from_superclass(method, default = nil) + if self == baseclass || !superclass.respond_to?(method, true) + default + else + value = superclass.send(method) + + # Ruby implements `dup` on Object, but raises a `TypeError` + # if the method is called on immediates. As a result, we + # don't have a good way to check whether dup will succeed + # without calling it and rescuing the TypeError. + begin + value.dup + rescue TypeError + value + end + + end + end + + # + # The basename of the program invoking the thor class. + # + def basename + File.basename($PROGRAM_NAME).split(" ").first + end + + # SIGNATURE: Sets the baseclass. This is where the superclass lookup + # finishes. + def baseclass #:nodoc: + end + + # SIGNATURE: Creates a new command if valid_command? is true. This method is + # called when a new method is added to the class. + def create_command(meth) #:nodoc: + end + alias_method :create_task, :create_command + + # SIGNATURE: Defines behavior when the initialize method is added to the + # class. + def initialize_added #:nodoc: + end + + # SIGNATURE: The hook invoked by start. + def dispatch(command, given_args, given_opts, config) #:nodoc: + raise NotImplementedError + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/command.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/command.rb new file mode 100644 index 0000000..040c971 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/command.rb @@ -0,0 +1,142 @@ +class Bundler::Thor + class Command < Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name) + FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/ + + def initialize(name, description, long_description, usage, options = nil) + super(name.to_s, description, long_description, usage, options || {}) + end + + def initialize_copy(other) #:nodoc: + super(other) + self.options = other.options.dup if other.options + end + + def hidden? + false + end + + # By default, a command invokes a method in the thor class. You can change this + # implementation to create custom commands. + def run(instance, args = []) + arity = nil + + if private_method?(instance) + instance.class.handle_no_command_error(name) + elsif public_method?(instance) + arity = instance.method(name).arity + instance.__send__(name, *args) + elsif local_method?(instance, :method_missing) + instance.__send__(:method_missing, name.to_sym, *args) + else + instance.class.handle_no_command_error(name) + end + rescue ArgumentError => e + handle_argument_error?(instance, e, caller) ? instance.class.handle_argument_error(self, e, args, arity) : (raise e) + rescue NoMethodError => e + handle_no_method_error?(instance, e, caller) ? instance.class.handle_no_command_error(name) : (raise e) + end + + # Returns the formatted usage by injecting given required arguments + # and required options into the given usage. + def formatted_usage(klass, namespace = true, subcommand = false) + if ancestor_name + formatted = "#{ancestor_name} ".dup # add space + elsif namespace + namespace = klass.namespace + formatted = "#{namespace.gsub(/^(default)/, '')}:".dup + end + formatted ||= "#{klass.namespace.split(':').last} ".dup if subcommand + + formatted ||= "".dup + + Array(usage).map do |specific_usage| + formatted_specific_usage = formatted + + formatted_specific_usage += required_arguments_for(klass, specific_usage) + + # Add required options + formatted_specific_usage += " #{required_options}" + + # Strip and go! + formatted_specific_usage.strip + end.join("\n") + end + + protected + + # Add usage with required arguments + def required_arguments_for(klass, usage) + if klass && !klass.arguments.empty? + usage.to_s.gsub(/^#{name}/) do |match| + match << " " << klass.arguments.map(&:usage).compact.join(" ") + end + else + usage.to_s + end + end + + def not_debugging?(instance) + !(instance.class.respond_to?(:debugging) && instance.class.debugging) + end + + def required_options + @required_options ||= options.map { |_, o| o.usage if o.required? }.compact.sort.join(" ") + end + + # Given a target, checks if this class name is a public method. + def public_method?(instance) #:nodoc: + !(instance.public_methods & [name.to_s, name.to_sym]).empty? + end + + def private_method?(instance) + !(instance.private_methods & [name.to_s, name.to_sym]).empty? + end + + def local_method?(instance, name) + methods = instance.public_methods(false) + instance.private_methods(false) + instance.protected_methods(false) + !(methods & [name.to_s, name.to_sym]).empty? + end + + def sans_backtrace(backtrace, caller) #:nodoc: + saned = backtrace.reject { |frame| frame =~ FILE_REGEXP || (frame =~ /\.java:/ && RUBY_PLATFORM =~ /java/) || (frame =~ %r{^kernel/} && RUBY_ENGINE =~ /rbx/) } + saned - caller + end + + def handle_argument_error?(instance, error, caller) + not_debugging?(instance) && (error.message =~ /wrong number of arguments/ || error.message =~ /given \d*, expected \d*/) && begin + saned = sans_backtrace(error.backtrace, caller) + saned.empty? || saned.size == 1 + end + end + + def handle_no_method_error?(instance, error, caller) + not_debugging?(instance) && + error.message =~ /^undefined method `#{name}' for #{Regexp.escape(instance.to_s)}$/ + end + end + Task = Command + + # A command that is hidden in help messages but still invocable. + class HiddenCommand < Command + def hidden? + true + end + end + HiddenTask = HiddenCommand + + # A dynamic command that handles method missing scenarios. + class DynamicCommand < Command + def initialize(name, options = nil) + super(name.to_s, "A dynamically-generated command", name.to_s, name.to_s, options) + end + + def run(instance, args = []) + if (instance.methods & [name.to_s, name.to_sym]).empty? + super + else + instance.class.handle_no_command_error(name) + end + end + end + DynamicTask = DynamicCommand +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb new file mode 100644 index 0000000..3c4483e --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb @@ -0,0 +1,103 @@ +class Bundler::Thor + module CoreExt #:nodoc: + # A hash with indifferent access and magic predicates. + # + # hash = Bundler::Thor::CoreExt::HashWithIndifferentAccess.new 'foo' => 'bar', 'baz' => 'bee', 'force' => true + # + # hash[:foo] #=> 'bar' + # hash['foo'] #=> 'bar' + # hash.foo? #=> true + # + class HashWithIndifferentAccess < ::Hash #:nodoc: + def initialize(hash = {}) + super() + hash.each do |key, value| + self[convert_key(key)] = value + end + end + + def [](key) + super(convert_key(key)) + end + + def []=(key, value) + super(convert_key(key), value) + end + + def delete(key) + super(convert_key(key)) + end + + def except(*keys) + dup.tap do |hash| + keys.each { |key| hash.delete(convert_key(key)) } + end + end + + def fetch(key, *args) + super(convert_key(key), *args) + end + + def key?(key) + super(convert_key(key)) + end + + def values_at(*indices) + indices.map { |key| self[convert_key(key)] } + end + + def merge(other) + dup.merge!(other) + end + + def merge!(other) + other.each do |key, value| + self[convert_key(key)] = value + end + self + end + + def reverse_merge(other) + self.class.new(other).merge(self) + end + + def reverse_merge!(other_hash) + replace(reverse_merge(other_hash)) + end + + def replace(other_hash) + super(other_hash) + end + + # Convert to a Hash with String keys. + def to_hash + Hash.new(default).merge!(self) + end + + protected + + def convert_key(key) + key.is_a?(Symbol) ? key.to_s : key + end + + # Magic predicates. For instance: + # + # options.force? # => !!options['force'] + # options.shebang # => "/usr/lib/local/ruby" + # options.test_framework?(:rspec) # => options[:test_framework] == :rspec + # + def method_missing(method, *args) + method = method.to_s + if method =~ /^(\w+)\?$/ + if args.empty? + !!self[$1] + else + self[$1] == args.first + end + else + self[method] + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/error.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/error.rb new file mode 100644 index 0000000..03f2ce8 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/error.rb @@ -0,0 +1,115 @@ +class Bundler::Thor + Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable) # rubocop:disable Naming/ConstantName + # In order to support versions of Ruby that don't have keyword + # arguments, we need our own spell checker class that doesn't take key + # words. Even though this code wouldn't be hit because of the check + # above, it's still necessary because the interpreter would otherwise be + # unable to parse the file. + class NoKwargSpellChecker < DidYouMean::SpellChecker # :nodoc: + def initialize(dictionary) + @dictionary = dictionary + end + end + + DidYouMean::Correctable + end + + # Bundler::Thor::Error is raised when it's caused by wrong usage of thor classes. Those + # errors have their backtrace suppressed and are nicely shown to the user. + # + # Errors that are caused by the developer, like declaring a method which + # overwrites a thor keyword, SHOULD NOT raise a Bundler::Thor::Error. This way, we + # ensure that developer errors are shown with full backtrace. + class Error < StandardError + end + + # Raised when a command was not found. + class UndefinedCommandError < Error + class SpellChecker + attr_reader :error + + def initialize(error) + @error = error + end + + def corrections + @corrections ||= spell_checker.correct(error.command).map(&:inspect) + end + + def spell_checker + NoKwargSpellChecker.new(error.all_commands) + end + end + + attr_reader :command, :all_commands + + def initialize(command, all_commands, namespace) + @command = command + @all_commands = all_commands + + message = "Could not find command #{command.inspect}" + message = namespace ? "#{message} in #{namespace.inspect} namespace." : "#{message}." + + super(message) + end + + prepend Correctable if Correctable + end + UndefinedTaskError = UndefinedCommandError + + class AmbiguousCommandError < Error + end + AmbiguousTaskError = AmbiguousCommandError + + # Raised when a command was found, but not invoked properly. + class InvocationError < Error + end + + class UnknownArgumentError < Error + class SpellChecker + attr_reader :error + + def initialize(error) + @error = error + end + + def corrections + @corrections ||= + error.unknown.flat_map { |unknown| spell_checker.correct(unknown) }.uniq.map(&:inspect) + end + + def spell_checker + @spell_checker ||= NoKwargSpellChecker.new(error.switches) + end + end + + attr_reader :switches, :unknown + + def initialize(switches, unknown) + @switches = switches + @unknown = unknown + + super("Unknown switches #{unknown.map(&:inspect).join(', ')}") + end + + prepend Correctable if Correctable + end + + class RequiredArgumentMissingError < InvocationError + end + + class MalformattedArgumentError < InvocationError + end + + if Correctable + if DidYouMean.respond_to?(:correct_error) + DidYouMean.correct_error(Bundler::Thor::UndefinedCommandError, UndefinedCommandError::SpellChecker) + DidYouMean.correct_error(Bundler::Thor::UnknownArgumentError, UnknownArgumentError::SpellChecker) + else + DidYouMean::SPELL_CHECKERS.merge!( + 'Bundler::Thor::UndefinedCommandError' => UndefinedCommandError::SpellChecker, + 'Bundler::Thor::UnknownArgumentError' => UnknownArgumentError::SpellChecker + ) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/group.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/group.rb new file mode 100644 index 0000000..7861d05 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/group.rb @@ -0,0 +1,281 @@ +require_relative "base" + +# Bundler::Thor has a special class called Bundler::Thor::Group. The main difference to Bundler::Thor class +# is that it invokes all commands at once. It also include some methods that allows +# invocations to be done at the class method, which are not available to Bundler::Thor +# commands. +class Bundler::Thor::Group + class << self + # The description for this Bundler::Thor::Group. If none is provided, but a source root + # exists, tries to find the USAGE one folder above it, otherwise searches + # in the superclass. + # + # ==== Parameters + # description:: The description for this Bundler::Thor::Group. + # + def desc(description = nil) + if description + @desc = description + else + @desc ||= from_superclass(:desc, nil) + end + end + + # Prints help information. + # + # ==== Options + # short:: When true, shows only usage. + # + def help(shell) + shell.say "Usage:" + shell.say " #{banner}\n" + shell.say + class_options_help(shell) + shell.say desc if desc + end + + # Stores invocations for this class merging with superclass values. + # + def invocations #:nodoc: + @invocations ||= from_superclass(:invocations, {}) + end + + # Stores invocation blocks used on invoke_from_option. + # + def invocation_blocks #:nodoc: + @invocation_blocks ||= from_superclass(:invocation_blocks, {}) + end + + # Invoke the given namespace or class given. It adds an instance + # method that will invoke the klass and command. You can give a block to + # configure how it will be invoked. + # + # The namespace/class given will have its options showed on the help + # usage. Check invoke_from_option for more information. + # + def invoke(*names, &block) + options = names.last.is_a?(Hash) ? names.pop : {} + verbose = options.fetch(:verbose, true) + + names.each do |name| + invocations[name] = false + invocation_blocks[name] = block if block_given? + + class_eval <<-METHOD, __FILE__, __LINE__ + 1 + def _invoke_#{name.to_s.gsub(/\W/, '_')} + klass, command = self.class.prepare_for_invocation(nil, #{name.inspect}) + + if klass + say_status :invoke, #{name.inspect}, #{verbose.inspect} + block = self.class.invocation_blocks[#{name.inspect}] + _invoke_for_class_method klass, command, &block + else + say_status :error, %(#{name.inspect} [not found]), :red + end + end + METHOD + end + end + + # Invoke a thor class based on the value supplied by the user to the + # given option named "name". A class option must be created before this + # method is invoked for each name given. + # + # ==== Examples + # + # class GemGenerator < Bundler::Thor::Group + # class_option :test_framework, :type => :string + # invoke_from_option :test_framework + # end + # + # ==== Boolean options + # + # In some cases, you want to invoke a thor class if some option is true or + # false. This is automatically handled by invoke_from_option. Then the + # option name is used to invoke the generator. + # + # ==== Preparing for invocation + # + # In some cases you want to customize how a specified hook is going to be + # invoked. You can do that by overwriting the class method + # prepare_for_invocation. The class method must necessarily return a klass + # and an optional command. + # + # ==== Custom invocations + # + # You can also supply a block to customize how the option is going to be + # invoked. The block receives two parameters, an instance of the current + # class and the klass to be invoked. + # + def invoke_from_option(*names, &block) + options = names.last.is_a?(Hash) ? names.pop : {} + verbose = options.fetch(:verbose, :white) + + names.each do |name| + unless class_options.key?(name) + raise ArgumentError, "You have to define the option #{name.inspect} " \ + "before setting invoke_from_option." + end + + invocations[name] = true + invocation_blocks[name] = block if block_given? + + class_eval <<-METHOD, __FILE__, __LINE__ + 1 + def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')} + return unless options[#{name.inspect}] + + value = options[#{name.inspect}] + value = #{name.inspect} if TrueClass === value + klass, command = self.class.prepare_for_invocation(#{name.inspect}, value) + + if klass + say_status :invoke, value, #{verbose.inspect} + block = self.class.invocation_blocks[#{name.inspect}] + _invoke_for_class_method klass, command, &block + else + say_status :error, %(\#{value} [not found]), :red + end + end + METHOD + end + end + + # Remove a previously added invocation. + # + # ==== Examples + # + # remove_invocation :test_framework + # + def remove_invocation(*names) + names.each do |name| + remove_command(name) + remove_class_option(name) + invocations.delete(name) + invocation_blocks.delete(name) + end + end + + # Overwrite class options help to allow invoked generators options to be + # shown recursively when invoking a generator. + # + def class_options_help(shell, groups = {}) #:nodoc: + get_options_from_invocations(groups, class_options) do |klass| + klass.send(:get_options_from_invocations, groups, class_options) + end + super(shell, groups) + end + + # Get invocations array and merge options from invocations. Those + # options are added to group_options hash. Options that already exists + # in base_options are not added twice. + # + def get_options_from_invocations(group_options, base_options) #:nodoc: # rubocop:disable MethodLength + invocations.each do |name, from_option| + value = if from_option + option = class_options[name] + option.type == :boolean ? name : option.default + else + name + end + next unless value + + klass, _ = prepare_for_invocation(name, value) + next unless klass && klass.respond_to?(:class_options) + + value = value.to_s + human_name = value.respond_to?(:classify) ? value.classify : value + + group_options[human_name] ||= [] + group_options[human_name] += klass.class_options.values.select do |class_option| + base_options[class_option.name.to_sym].nil? && class_option.group.nil? && + !group_options.values.flatten.any? { |i| i.name == class_option.name } + end + + yield klass if block_given? + end + end + + # Returns commands ready to be printed. + def printable_commands(*) + item = [] + item << banner + item << (desc ? "# #{desc.gsub(/\s+/m, ' ')}" : "") + [item] + end + alias_method :printable_tasks, :printable_commands + + def handle_argument_error(command, error, _args, arity) #:nodoc: + msg = "#{basename} #{command.name} takes #{arity} argument".dup + msg << "s" if arity > 1 + msg << ", but it should not." + raise error, msg + end + + protected + + # The method responsible for dispatching given the args. + def dispatch(command, given_args, given_opts, config) #:nodoc: + if Bundler::Thor::HELP_MAPPINGS.include?(given_args.first) + help(config[:shell]) + return + end + + args, opts = Bundler::Thor::Options.split(given_args) + opts = given_opts || opts + + instance = new(args, opts, config) + yield instance if block_given? + + if command + instance.invoke_command(all_commands[command]) + else + instance.invoke_all + end + end + + # The banner for this class. You can customize it if you are invoking the + # thor class by another ways which is not the Bundler::Thor::Runner. + def banner + "#{basename} #{self_command.formatted_usage(self, false)}" + end + + # Represents the whole class as a command. + def self_command #:nodoc: + Bundler::Thor::DynamicCommand.new(namespace, class_options) + end + alias_method :self_task, :self_command + + def baseclass #:nodoc: + Bundler::Thor::Group + end + + def create_command(meth) #:nodoc: + commands[meth.to_s] = Bundler::Thor::Command.new(meth, nil, nil, nil, nil) + true + end + alias_method :create_task, :create_command + end + + include Bundler::Thor::Base + +protected + + # Shortcut to invoke with padding and block handling. Use internally by + # invoke and invoke_from_option class methods. + def _invoke_for_class_method(klass, command = nil, *args, &block) #:nodoc: + with_padding do + if block + case block.arity + when 3 + yield(self, klass, command) + when 2 + yield(self, klass) + when 1 + instance_exec(klass, &block) + end + else + invoke klass, command, *args + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/invocation.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/invocation.rb new file mode 100644 index 0000000..248a466 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/invocation.rb @@ -0,0 +1,178 @@ +class Bundler::Thor + module Invocation + def self.included(base) #:nodoc: + super(base) + base.extend ClassMethods + end + + module ClassMethods + # This method is responsible for receiving a name and find the proper + # class and command for it. The key is an optional parameter which is + # available only in class methods invocations (i.e. in Bundler::Thor::Group). + def prepare_for_invocation(key, name) #:nodoc: + case name + when Symbol, String + Bundler::Thor::Util.find_class_and_command_by_namespace(name.to_s, !key) + else + name + end + end + end + + # Make initializer aware of invocations and the initialization args. + def initialize(args = [], options = {}, config = {}, &block) #:nodoc: + @_invocations = config[:invocations] || Hash.new { |h, k| h[k] = [] } + @_initializer = [args, options, config] + super + end + + # Make the current command chain accessible with in a Bundler::Thor-(sub)command + def current_command_chain + @_invocations.values.flatten.map(&:to_sym) + end + + # Receives a name and invokes it. The name can be a string (either "command" or + # "namespace:command"), a Bundler::Thor::Command, a Class or a Bundler::Thor instance. If the + # command cannot be guessed by name, it can also be supplied as second argument. + # + # You can also supply the arguments, options and configuration values for + # the command to be invoked, if none is given, the same values used to + # initialize the invoker are used to initialize the invoked. + # + # When no name is given, it will invoke the default command of the current class. + # + # ==== Examples + # + # class A < Bundler::Thor + # def foo + # invoke :bar + # invoke "b:hello", ["Erik"] + # end + # + # def bar + # invoke "b:hello", ["Erik"] + # end + # end + # + # class B < Bundler::Thor + # def hello(name) + # puts "hello #{name}" + # end + # end + # + # You can notice that the method "foo" above invokes two commands: "bar", + # which belongs to the same class and "hello" which belongs to the class B. + # + # By using an invocation system you ensure that a command is invoked only once. + # In the example above, invoking "foo" will invoke "b:hello" just once, even + # if it's invoked later by "bar" method. + # + # When class A invokes class B, all arguments used on A initialization are + # supplied to B. This allows lazy parse of options. Let's suppose you have + # some rspec commands: + # + # class Rspec < Bundler::Thor::Group + # class_option :mock_framework, :type => :string, :default => :rr + # + # def invoke_mock_framework + # invoke "rspec:#{options[:mock_framework]}" + # end + # end + # + # As you noticed, it invokes the given mock framework, which might have its + # own options: + # + # class Rspec::RR < Bundler::Thor::Group + # class_option :style, :type => :string, :default => :mock + # end + # + # Since it's not rspec concern to parse mock framework options, when RR + # is invoked all options are parsed again, so RR can extract only the options + # that it's going to use. + # + # If you want Rspec::RR to be initialized with its own set of options, you + # have to do that explicitly: + # + # invoke "rspec:rr", [], :style => :foo + # + # Besides giving an instance, you can also give a class to invoke: + # + # invoke Rspec::RR, [], :style => :foo + # + def invoke(name = nil, *args) + if name.nil? + warn "[Bundler::Thor] Calling invoke() without argument is deprecated. Please use invoke_all instead.\n#{caller.join("\n")}" + return invoke_all + end + + args.unshift(nil) if args.first.is_a?(Array) || args.first.nil? + command, args, opts, config = args + + klass, command = _retrieve_class_and_command(name, command) + raise "Missing Bundler::Thor class for invoke #{name}" unless klass + raise "Expected Bundler::Thor class, got #{klass}" unless klass <= Bundler::Thor::Base + + args, opts, config = _parse_initialization_options(args, opts, config) + klass.send(:dispatch, command, args, opts, config) do |instance| + instance.parent_options = options + end + end + + # Invoke the given command if the given args. + def invoke_command(command, *args) #:nodoc: + current = @_invocations[self.class] + + unless current.include?(command.name) + current << command.name + command.run(self, *args) + end + end + alias_method :invoke_task, :invoke_command + + # Invoke all commands for the current instance. + def invoke_all #:nodoc: + self.class.all_commands.map { |_, command| invoke_command(command) } + end + + # Invokes using shell padding. + def invoke_with_padding(*args) + with_padding { invoke(*args) } + end + + protected + + # Configuration values that are shared between invocations. + def _shared_configuration #:nodoc: + {:invocations => @_invocations} + end + + # This method simply retrieves the class and command to be invoked. + # If the name is nil or the given name is a command in the current class, + # use the given name and return self as class. Otherwise, call + # prepare_for_invocation in the current class. + def _retrieve_class_and_command(name, sent_command = nil) #:nodoc: + if name.nil? + [self.class, nil] + elsif self.class.all_commands[name.to_s] + [self.class, name.to_s] + else + klass, command = self.class.prepare_for_invocation(nil, name) + [klass, command || sent_command] + end + end + alias_method :_retrieve_class_and_task, :_retrieve_class_and_command + + # Initialize klass using values stored in the @_initializer. + def _parse_initialization_options(args, opts, config) #:nodoc: + stored_args, stored_opts, stored_config = @_initializer + + args ||= stored_args.dup + opts ||= stored_opts.dup + + config ||= {} + config = stored_config.merge(_shared_configuration).merge!(config) + + [args, opts, config] + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/line_editor.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/line_editor.rb new file mode 100644 index 0000000..5c0c336 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/line_editor.rb @@ -0,0 +1,17 @@ +require_relative "line_editor/basic" +require_relative "line_editor/readline" + +class Bundler::Thor + module LineEditor + def self.readline(prompt, options = {}) + best_available.new(prompt, options).readline + end + + def self.best_available + [ + Bundler::Thor::LineEditor::Readline, + Bundler::Thor::LineEditor::Basic + ].detect(&:available?) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/line_editor/basic.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/line_editor/basic.rb new file mode 100644 index 0000000..fe3d7c9 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/line_editor/basic.rb @@ -0,0 +1,37 @@ +class Bundler::Thor + module LineEditor + class Basic + attr_reader :prompt, :options + + def self.available? + true + end + + def initialize(prompt, options) + @prompt = prompt + @options = options + end + + def readline + $stdout.print(prompt) + get_input + end + + private + + def get_input + if echo? + $stdin.gets + else + # Lazy-load io/console since it is gem-ified as of 2.3 + require "io/console" + $stdin.noecho(&:gets) + end + end + + def echo? + options.fetch(:echo, true) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/line_editor/readline.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/line_editor/readline.rb new file mode 100644 index 0000000..120eadd --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/line_editor/readline.rb @@ -0,0 +1,88 @@ +class Bundler::Thor + module LineEditor + class Readline < Basic + def self.available? + begin + require "readline" + rescue LoadError + end + + Object.const_defined?(:Readline) + end + + def readline + if echo? + ::Readline.completion_append_character = nil + # rb-readline does not allow Readline.completion_proc= to receive nil. + if complete = completion_proc + ::Readline.completion_proc = complete + end + ::Readline.readline(prompt, add_to_history?) + else + super + end + end + + private + + def add_to_history? + options.fetch(:add_to_history, true) + end + + def completion_proc + if use_path_completion? + proc { |text| PathCompletion.new(text).matches } + elsif completion_options.any? + proc do |text| + completion_options.select { |option| option.start_with?(text) } + end + end + end + + def completion_options + options.fetch(:limited_to, []) + end + + def use_path_completion? + options.fetch(:path, false) + end + + class PathCompletion + attr_reader :text + private :text + + def initialize(text) + @text = text + end + + def matches + relative_matches + end + + private + + def relative_matches + absolute_matches.map { |path| path.sub(base_path, "") } + end + + def absolute_matches + Dir[glob_pattern].map do |path| + if File.directory?(path) + "#{path}/" + else + path + end + end + end + + def glob_pattern + "#{base_path}#{text}*" + end + + def base_path + "#{Dir.pwd}/" + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/nested_context.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/nested_context.rb new file mode 100644 index 0000000..fd36b9d --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/nested_context.rb @@ -0,0 +1,29 @@ +class Bundler::Thor + class NestedContext + def initialize + @depth = 0 + end + + def enter + push + + yield + ensure + pop + end + + def entered? + @depth > 0 + end + + private + + def push + @depth += 1 + end + + def pop + @depth -= 1 + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser.rb new file mode 100644 index 0000000..4539473 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser.rb @@ -0,0 +1,4 @@ +require_relative "parser/argument" +require_relative "parser/arguments" +require_relative "parser/option" +require_relative "parser/options" diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser/argument.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser/argument.rb new file mode 100644 index 0000000..dfe7398 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser/argument.rb @@ -0,0 +1,70 @@ +class Bundler::Thor + class Argument #:nodoc: + VALID_TYPES = [:numeric, :hash, :array, :string] + + attr_reader :name, :description, :enum, :required, :type, :default, :banner + alias_method :human_name, :name + + def initialize(name, options = {}) + class_name = self.class.name.split("::").last + + type = options[:type] + + raise ArgumentError, "#{class_name} name can't be nil." if name.nil? + raise ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s." if type && !valid_type?(type) + + @name = name.to_s + @description = options[:desc] + @required = options.key?(:required) ? options[:required] : true + @type = (type || :string).to_sym + @default = options[:default] + @banner = options[:banner] || default_banner + @enum = options[:enum] + + validate! # Trigger specific validations + end + + def usage + required? ? banner : "[#{banner}]" + end + + def required? + required + end + + def show_default? + case default + when Array, String, Hash + !default.empty? + else + default + end + end + + protected + + def validate! + raise ArgumentError, "An argument cannot be required and have default value." if required? && !default.nil? + raise ArgumentError, "An argument cannot have an enum other than an array." if @enum && !@enum.is_a?(Array) + end + + def valid_type?(type) + self.class::VALID_TYPES.include?(type.to_sym) + end + + def default_banner + case type + when :boolean + nil + when :string, :default + human_name.upcase + when :numeric + "N" + when :hash + "key:value" + when :array + "one two three" + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser/arguments.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser/arguments.rb new file mode 100644 index 0000000..3a5d82c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser/arguments.rb @@ -0,0 +1,179 @@ +class Bundler::Thor + class Arguments #:nodoc: # rubocop:disable ClassLength + NUMERIC = /[-+]?(\d*\.\d+|\d+)/ + + # Receives an array of args and returns two arrays, one with arguments + # and one with switches. + # + def self.split(args) + arguments = [] + + args.each do |item| + break if item.is_a?(String) && item =~ /^-/ + arguments << item + end + + [arguments, args[Range.new(arguments.size, -1)]] + end + + def self.parse(*args) + to_parse = args.pop + new(*args).parse(to_parse) + end + + # Takes an array of Bundler::Thor::Argument objects. + # + def initialize(arguments = []) + @assigns = {} + @non_assigned_required = [] + @switches = arguments + + arguments.each do |argument| + if !argument.default.nil? + begin + @assigns[argument.human_name] = argument.default.dup + rescue TypeError # Compatibility shim for un-dup-able Fixnum in Ruby < 2.4 + @assigns[argument.human_name] = argument.default + end + elsif argument.required? + @non_assigned_required << argument + end + end + end + + def parse(args) + @pile = args.dup + + @switches.each do |argument| + break unless peek + @non_assigned_required.delete(argument) + @assigns[argument.human_name] = send(:"parse_#{argument.type}", argument.human_name) + end + + check_requirement! + @assigns + end + + def remaining + @pile + end + + private + + def no_or_skip?(arg) + arg =~ /^--(no|skip)-([-\w]+)$/ + $2 + end + + def last? + @pile.empty? + end + + def peek + @pile.first + end + + def shift + @pile.shift + end + + def unshift(arg) + if arg.is_a?(Array) + @pile = arg + @pile + else + @pile.unshift(arg) + end + end + + def current_is_value? + peek && peek.to_s !~ /^-{1,2}\S+/ + end + + # Runs through the argument array getting strings that contains ":" and + # mark it as a hash: + # + # [ "name:string", "age:integer" ] + # + # Becomes: + # + # { "name" => "string", "age" => "integer" } + # + def parse_hash(name) + return shift if peek.is_a?(Hash) + hash = {} + + while current_is_value? && peek.include?(":") + key, value = shift.split(":", 2) + raise MalformattedArgumentError, "You can't specify '#{key}' more than once in option '#{name}'; got #{key}:#{hash[key]} and #{key}:#{value}" if hash.include? key + hash[key] = value + end + hash + end + + # Runs through the argument array getting all strings until no string is + # found or a switch is found. + # + # ["a", "b", "c"] + # + # And returns it as an array: + # + # ["a", "b", "c"] + # + def parse_array(name) + return shift if peek.is_a?(Array) + array = [] + array << shift while current_is_value? + array + end + + # Check if the peek is numeric format and return a Float or Integer. + # Check if the peek is included in enum if enum is provided. + # Otherwise raises an error. + # + def parse_numeric(name) + return shift if peek.is_a?(Numeric) + + unless peek =~ NUMERIC && $& == peek + raise MalformattedArgumentError, "Expected numeric value for '#{name}'; got #{peek.inspect}" + end + + value = $&.index(".") ? shift.to_f : shift.to_i + if @switches.is_a?(Hash) && switch = @switches[name] + if switch.enum && !switch.enum.include?(value) + raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}" + end + end + value + end + + # Parse string: + # for --string-arg, just return the current value in the pile + # for --no-string-arg, nil + # Check if the peek is included in enum if enum is provided. Otherwise raises an error. + # + def parse_string(name) + if no_or_skip?(name) + nil + else + value = shift + if @switches.is_a?(Hash) && switch = @switches[name] + if switch.enum && !switch.enum.include?(value) + raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}" + end + end + value + end + end + + # Raises an error if @non_assigned_required array is not empty. + # + def check_requirement! + return if @non_assigned_required.empty? + names = @non_assigned_required.map do |o| + o.respond_to?(:switch_name) ? o.switch_name : o.human_name + end.join("', '") + class_name = self.class.name.split("::").last.downcase + raise RequiredArgumentMissingError, "No value provided for required #{class_name} '#{names}'" + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser/option.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser/option.rb new file mode 100644 index 0000000..5a5af6f --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser/option.rb @@ -0,0 +1,159 @@ +class Bundler::Thor + class Option < Argument #:nodoc: + attr_reader :aliases, :group, :lazy_default, :hide, :repeatable + + VALID_TYPES = [:boolean, :numeric, :hash, :array, :string] + + def initialize(name, options = {}) + @check_default_type = options[:check_default_type] + options[:required] = false unless options.key?(:required) + @repeatable = options.fetch(:repeatable, false) + super + @lazy_default = options[:lazy_default] + @group = options[:group].to_s.capitalize if options[:group] + @aliases = Array(options[:aliases]) + @hide = options[:hide] + end + + # This parse quick options given as method_options. It makes several + # assumptions, but you can be more specific using the option method. + # + # parse :foo => "bar" + # #=> Option foo with default value bar + # + # parse [:foo, :baz] => "bar" + # #=> Option foo with default value bar and alias :baz + # + # parse :foo => :required + # #=> Required option foo without default value + # + # parse :foo => 2 + # #=> Option foo with default value 2 and type numeric + # + # parse :foo => :numeric + # #=> Option foo without default value and type numeric + # + # parse :foo => true + # #=> Option foo with default value true and type boolean + # + # The valid types are :boolean, :numeric, :hash, :array and :string. If none + # is given a default type is assumed. This default type accepts arguments as + # string (--foo=value) or booleans (just --foo). + # + # By default all options are optional, unless :required is given. + # + def self.parse(key, value) + if key.is_a?(Array) + name, *aliases = key + else + name = key + aliases = [] + end + + name = name.to_s + default = value + + type = case value + when Symbol + default = nil + if VALID_TYPES.include?(value) + value + elsif required = (value == :required) # rubocop:disable AssignmentInCondition + :string + end + when TrueClass, FalseClass + :boolean + when Numeric + :numeric + when Hash, Array, String + value.class.name.downcase.to_sym + end + + new(name.to_s, :required => required, :type => type, :default => default, :aliases => aliases) + end + + def switch_name + @switch_name ||= dasherized? ? name : dasherize(name) + end + + def human_name + @human_name ||= dasherized? ? undasherize(name) : name + end + + def usage(padding = 0) + sample = if banner && !banner.to_s.empty? + "#{switch_name}=#{banner}".dup + else + switch_name + end + + sample = "[#{sample}]".dup unless required? + + if boolean? + sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.start_with?("no-") + end + + if aliases.empty? + (" " * padding) << sample + else + "#{aliases.join(', ')}, #{sample}" + end + end + + VALID_TYPES.each do |type| + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{type}? + self.type == #{type.inspect} + end + RUBY + end + + protected + + def validate! + raise ArgumentError, "An option cannot be boolean and required." if boolean? && required? + validate_default_type! + end + + def validate_default_type! + default_type = case @default + when nil + return + when TrueClass, FalseClass + required? ? :string : :boolean + when Numeric + :numeric + when Symbol + :string + when Hash, Array, String + @default.class.name.downcase.to_sym + end + + expected_type = (@repeatable && @type != :hash) ? :array : @type + + if default_type != expected_type + err = "Expected #{expected_type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" + + if @check_default_type + raise ArgumentError, err + elsif @check_default_type == nil + Bundler::Thor.deprecation_warning "#{err}.\n" + + 'This will be rejected in the future unless you explicitly pass the options `check_default_type: false`' + + ' or call `allow_incompatible_default_type!` in your code' + end + end + end + + def dasherized? + name.index("-") == 0 + end + + def undasherize(str) + str.sub(/^-{1,2}/, "") + end + + def dasherize(str) + (str.length > 1 ? "--" : "-") + str.tr("_", "-") + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser/options.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser/options.rb new file mode 100644 index 0000000..5bd97ab --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/parser/options.rb @@ -0,0 +1,255 @@ +class Bundler::Thor + class Options < Arguments #:nodoc: # rubocop:disable ClassLength + LONG_RE = /^(--\w+(?:-\w+)*)$/ + SHORT_RE = /^(-[a-z])$/i + EQ_RE = /^(--\w+(?:-\w+)*|-[a-z])=(.*)$/i + SHORT_SQ_RE = /^-([a-z]{2,})$/i # Allow either -x -v or -xv style for single char args + SHORT_NUM = /^(-[a-z])#{NUMERIC}$/i + OPTS_END = "--".freeze + + # Receives a hash and makes it switches. + def self.to_switches(options) + options.map do |key, value| + case value + when true + "--#{key}" + when Array + "--#{key} #{value.map(&:inspect).join(' ')}" + when Hash + "--#{key} #{value.map { |k, v| "#{k}:#{v}" }.join(' ')}" + when nil, false + nil + else + "--#{key} #{value.inspect}" + end + end.compact.join(" ") + end + + # Takes a hash of Bundler::Thor::Option and a hash with defaults. + # + # If +stop_on_unknown+ is true, #parse will stop as soon as it encounters + # an unknown option or a regular argument. + def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false, disable_required_check = false) + @stop_on_unknown = stop_on_unknown + @disable_required_check = disable_required_check + options = hash_options.values + super(options) + + # Add defaults + defaults.each do |key, value| + @assigns[key.to_s] = value + @non_assigned_required.delete(hash_options[key]) + end + + @shorts = {} + @switches = {} + @extra = [] + @stopped_parsing_after_extra_index = nil + @is_treated_as_value = false + + options.each do |option| + @switches[option.switch_name] = option + + option.aliases.each do |short| + name = short.to_s.sub(/^(?!\-)/, "-") + @shorts[name] ||= option.switch_name + end + end + end + + def remaining + @extra + end + + def peek + return super unless @parsing_options + + result = super + if result == OPTS_END + shift + @parsing_options = false + @stopped_parsing_after_extra_index ||= @extra.size + super + else + result + end + end + + def shift + @is_treated_as_value = false + super + end + + def unshift(arg, is_value: false) + @is_treated_as_value = is_value + super(arg) + end + + def parse(args) # rubocop:disable MethodLength + @pile = args.dup + @is_treated_as_value = false + @parsing_options = true + + while peek + if parsing_options? + match, is_switch = current_is_switch? + shifted = shift + + if is_switch + case shifted + when SHORT_SQ_RE + unshift($1.split("").map { |f| "-#{f}" }) + next + when EQ_RE + unshift($2, is_value: true) + switch = $1 + when SHORT_NUM + unshift($2) + switch = $1 + when LONG_RE, SHORT_RE + switch = $1 + end + + switch = normalize_switch(switch) + option = switch_option(switch) + result = parse_peek(switch, option) + assign_result!(option, result) + elsif @stop_on_unknown + @parsing_options = false + @extra << shifted + @stopped_parsing_after_extra_index ||= @extra.size + @extra << shift while peek + break + elsif match + @extra << shifted + @extra << shift while peek && peek !~ /^-/ + else + @extra << shifted + end + else + @extra << shift + end + end + + check_requirement! unless @disable_required_check + + assigns = Bundler::Thor::CoreExt::HashWithIndifferentAccess.new(@assigns) + assigns.freeze + assigns + end + + def check_unknown! + to_check = @stopped_parsing_after_extra_index ? @extra[0...@stopped_parsing_after_extra_index] : @extra + + # an unknown option starts with - or -- and has no more --'s afterward. + unknown = to_check.select { |str| str =~ /^--?(?:(?!--).)*$/ } + raise UnknownArgumentError.new(@switches.keys, unknown) unless unknown.empty? + end + + protected + + def assign_result!(option, result) + if option.repeatable && option.type == :hash + (@assigns[option.human_name] ||= {}).merge!(result) + elsif option.repeatable + (@assigns[option.human_name] ||= []) << result + else + @assigns[option.human_name] = result + end + end + + # Check if the current value in peek is a registered switch. + # + # Two booleans are returned. The first is true if the current value + # starts with a hyphen; the second is true if it is a registered switch. + def current_is_switch? + return [false, false] if @is_treated_as_value + case peek + when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM + [true, switch?($1)] + when SHORT_SQ_RE + [true, $1.split("").any? { |f| switch?("-#{f}") }] + else + [false, false] + end + end + + def current_is_switch_formatted? + return false if @is_treated_as_value + case peek + when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM, SHORT_SQ_RE + true + else + false + end + end + + def current_is_value? + return true if @is_treated_as_value + peek && (!parsing_options? || super) + end + + def switch?(arg) + !switch_option(normalize_switch(arg)).nil? + end + + def switch_option(arg) + if match = no_or_skip?(arg) # rubocop:disable AssignmentInCondition + @switches[arg] || @switches["--#{match}"] + else + @switches[arg] + end + end + + # Check if the given argument is actually a shortcut. + # + def normalize_switch(arg) + (@shorts[arg] || arg).tr("_", "-") + end + + def parsing_options? + peek + @parsing_options + end + + # Parse boolean values which can be given as --foo=true, --foo or --no-foo. + # + def parse_boolean(switch) + if current_is_value? + if ["true", "TRUE", "t", "T", true].include?(peek) + shift + true + elsif ["false", "FALSE", "f", "F", false].include?(peek) + shift + false + else + @switches.key?(switch) || !no_or_skip?(switch) + end + else + @switches.key?(switch) || !no_or_skip?(switch) + end + end + + # Parse the value at the peek analyzing if it requires an input or not. + # + def parse_peek(switch, option) + if parsing_options? && (current_is_switch_formatted? || last?) + if option.boolean? + # No problem for boolean types + elsif no_or_skip?(switch) + return nil # User set value to nil + elsif option.string? && !option.required? + # Return the default if there is one, else the human name + return option.lazy_default || option.default || option.human_name + elsif option.lazy_default + return option.lazy_default + else + raise MalformattedArgumentError, "No value provided for option '#{switch}'" + end + end + + @non_assigned_required.delete(option) + send(:"parse_#{option.type}", switch) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/rake_compat.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/rake_compat.rb new file mode 100644 index 0000000..f8f8637 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/rake_compat.rb @@ -0,0 +1,72 @@ +require "rake" +require "rake/dsl_definition" + +class Bundler::Thor + # Adds a compatibility layer to your Bundler::Thor classes which allows you to use + # rake package tasks. For example, to use rspec rake tasks, one can do: + # + # require 'bundler/vendor/thor/lib/thor/rake_compat' + # require 'rspec/core/rake_task' + # + # class Default < Bundler::Thor + # include Bundler::Thor::RakeCompat + # + # RSpec::Core::RakeTask.new(:spec) do |t| + # t.spec_opts = ['--options', './.rspec'] + # t.spec_files = FileList['spec/**/*_spec.rb'] + # end + # end + # + module RakeCompat + include Rake::DSL if defined?(Rake::DSL) + + def self.rake_classes + @rake_classes ||= [] + end + + def self.included(base) + super(base) + # Hack. Make rakefile point to invoker, so rdoc task is generated properly. + rakefile = File.basename(caller[0].match(/(.*):\d+/)[1]) + Rake.application.instance_variable_set(:@rakefile, rakefile) + rake_classes << base + end + end +end + +# override task on (main), for compatibility with Rake 0.9 +instance_eval do + alias rake_namespace namespace + + def task(*) + task = super + + if klass = Bundler::Thor::RakeCompat.rake_classes.last # rubocop:disable AssignmentInCondition + non_namespaced_name = task.name.split(":").last + + description = non_namespaced_name + description << task.arg_names.map { |n| n.to_s.upcase }.join(" ") + description.strip! + + klass.desc description, Rake.application.last_description || non_namespaced_name + Rake.application.last_description = nil + klass.send :define_method, non_namespaced_name do |*args| + Rake::Task[task.name.to_sym].invoke(*args) + end + end + + task + end + + def namespace(name) + if klass = Bundler::Thor::RakeCompat.rake_classes.last # rubocop:disable AssignmentInCondition + const_name = Bundler::Thor::Util.camel_case(name.to_s).to_sym + klass.const_set(const_name, Class.new(Bundler::Thor)) + new_klass = klass.const_get(const_name) + Bundler::Thor::RakeCompat.rake_classes << new_klass + end + + super + Bundler::Thor::RakeCompat.rake_classes.pop + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/runner.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/runner.rb new file mode 100644 index 0000000..54c5525 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/runner.rb @@ -0,0 +1,325 @@ +require_relative "../thor" +require_relative "group" + +require "yaml" +require "digest/md5" +require "pathname" + +class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLength + autoload :OpenURI, "open-uri" + + map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version + + def self.banner(command, all = false, subcommand = false) + "thor " + command.formatted_usage(self, all, subcommand) + end + + def self.exit_on_failure? + true + end + + # Override Bundler::Thor#help so it can give information about any class and any method. + # + def help(meth = nil) + if meth && !respond_to?(meth) + initialize_thorfiles(meth) + klass, command = Bundler::Thor::Util.find_class_and_command_by_namespace(meth) + self.class.handle_no_command_error(command, false) if klass.nil? + klass.start(["-h", command].compact, :shell => shell) + else + super + end + end + + # If a command is not found on Bundler::Thor::Runner, method missing is invoked and + # Bundler::Thor::Runner is then responsible for finding the command in all classes. + # + def method_missing(meth, *args) + meth = meth.to_s + initialize_thorfiles(meth) + klass, command = Bundler::Thor::Util.find_class_and_command_by_namespace(meth) + self.class.handle_no_command_error(command, false) if klass.nil? + args.unshift(command) if command + klass.start(args, :shell => shell) + end + + desc "install NAME", "Install an optionally named Bundler::Thor file into your system commands" + method_options :as => :string, :relative => :boolean, :force => :boolean + def install(name) # rubocop:disable MethodLength + initialize_thorfiles + + # If a directory name is provided as the argument, look for a 'main.thor' + # command in said directory. + begin + if File.directory?(File.expand_path(name)) + base = File.join(name, "main.thor") + package = :directory + contents = open(base, &:read) + else + base = name + package = :file + contents = open(name, &:read) + end + rescue OpenURI::HTTPError + raise Error, "Error opening URI '#{name}'" + rescue Errno::ENOENT + raise Error, "Error opening file '#{name}'" + end + + say "Your Thorfile contains:" + say contents + + unless options["force"] + return false if no?("Do you wish to continue [y/N]?") + end + + as = options["as"] || begin + first_line = contents.split("\n")[0] + (match = first_line.match(/\s*#\s*module:\s*([^\n]*)/)) ? match[1].strip : nil + end + + unless as + basename = File.basename(name) + as = ask("Please specify a name for #{name} in the system repository [#{basename}]:") + as = basename if as.empty? + end + + location = if options[:relative] || name =~ %r{^https?://} + name + else + File.expand_path(name) + end + + thor_yaml[as] = { + :filename => Digest::MD5.hexdigest(name + as), + :location => location, + :namespaces => Bundler::Thor::Util.namespaces_in_content(contents, base) + } + + save_yaml(thor_yaml) + say "Storing thor file in your system repository" + destination = File.join(thor_root, thor_yaml[as][:filename]) + + if package == :file + File.open(destination, "w") { |f| f.puts contents } + else + require "fileutils" + FileUtils.cp_r(name, destination) + end + + thor_yaml[as][:filename] # Indicate success + end + + desc "version", "Show Bundler::Thor version" + def version + require_relative "version" + say "Bundler::Thor #{Bundler::Thor::VERSION}" + end + + desc "uninstall NAME", "Uninstall a named Bundler::Thor module" + def uninstall(name) + raise Error, "Can't find module '#{name}'" unless thor_yaml[name] + say "Uninstalling #{name}." + require "fileutils" + FileUtils.rm_rf(File.join(thor_root, (thor_yaml[name][:filename]).to_s)) + + thor_yaml.delete(name) + save_yaml(thor_yaml) + + puts "Done." + end + + desc "update NAME", "Update a Bundler::Thor file from its original location" + def update(name) + raise Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location] + + say "Updating '#{name}' from #{thor_yaml[name][:location]}" + + old_filename = thor_yaml[name][:filename] + self.options = options.merge("as" => name) + + if File.directory? File.expand_path(name) + require "fileutils" + FileUtils.rm_rf(File.join(thor_root, old_filename)) + + thor_yaml.delete(old_filename) + save_yaml(thor_yaml) + + filename = install(name) + else + filename = install(thor_yaml[name][:location]) + end + + File.delete(File.join(thor_root, old_filename)) unless filename == old_filename + end + + desc "installed", "List the installed Bundler::Thor modules and commands" + method_options :internal => :boolean + def installed + initialize_thorfiles(nil, true) + display_klasses(true, options["internal"]) + end + + desc "list [SEARCH]", "List the available thor commands (--substring means .*SEARCH)" + method_options :substring => :boolean, :group => :string, :all => :boolean, :debug => :boolean + def list(search = "") + initialize_thorfiles + + search = ".*#{search}" if options["substring"] + search = /^#{search}.*/i + group = options[:group] || "standard" + + klasses = Bundler::Thor::Base.subclasses.select do |k| + (options[:all] || k.group == group) && k.namespace =~ search + end + + display_klasses(false, false, klasses) + end + +private + + def thor_root + Bundler::Thor::Util.thor_root + end + + def thor_yaml + @thor_yaml ||= begin + yaml_file = File.join(thor_root, "thor.yml") + yaml = YAML.load_file(yaml_file) if File.exist?(yaml_file) + yaml || {} + end + end + + # Save the yaml file. If none exists in thor root, creates one. + # + def save_yaml(yaml) + yaml_file = File.join(thor_root, "thor.yml") + + unless File.exist?(yaml_file) + require "fileutils" + FileUtils.mkdir_p(thor_root) + yaml_file = File.join(thor_root, "thor.yml") + FileUtils.touch(yaml_file) + end + + File.open(yaml_file, "w") { |f| f.puts yaml.to_yaml } + end + + # Load the Thorfiles. If relevant_to is supplied, looks for specific files + # in the thor_root instead of loading them all. + # + # By default, it also traverses the current path until find Bundler::Thor files, as + # described in thorfiles. This look up can be skipped by supplying + # skip_lookup true. + # + def initialize_thorfiles(relevant_to = nil, skip_lookup = false) + thorfiles(relevant_to, skip_lookup).each do |f| + Bundler::Thor::Util.load_thorfile(f, nil, options[:debug]) unless Bundler::Thor::Base.subclass_files.keys.include?(File.expand_path(f)) + end + end + + # Finds Thorfiles by traversing from your current directory down to the root + # directory of your system. If at any time we find a Bundler::Thor file, we stop. + # + # We also ensure that system-wide Thorfiles are loaded first, so local + # Thorfiles can override them. + # + # ==== Example + # + # If we start at /Users/wycats/dev/thor ... + # + # 1. /Users/wycats/dev/thor + # 2. /Users/wycats/dev + # 3. /Users/wycats <-- we find a Thorfile here, so we stop + # + # Suppose we start at c:\Documents and Settings\james\dev\thor ... + # + # 1. c:\Documents and Settings\james\dev\thor + # 2. c:\Documents and Settings\james\dev + # 3. c:\Documents and Settings\james + # 4. c:\Documents and Settings + # 5. c:\ <-- no Thorfiles found! + # + def thorfiles(relevant_to = nil, skip_lookup = false) + thorfiles = [] + + unless skip_lookup + Pathname.pwd.ascend do |path| + thorfiles = Bundler::Thor::Util.globs_for(path).map { |g| Dir[g] }.flatten + break unless thorfiles.empty? + end + end + + files = (relevant_to ? thorfiles_relevant_to(relevant_to) : Bundler::Thor::Util.thor_root_glob) + files += thorfiles + files -= ["#{thor_root}/thor.yml"] + + files.map! do |file| + File.directory?(file) ? File.join(file, "main.thor") : file + end + end + + # Load Thorfiles relevant to the given method. If you provide "foo:bar" it + # will load all thor files in the thor.yaml that has "foo" e "foo:bar" + # namespaces registered. + # + def thorfiles_relevant_to(meth) + lookup = [meth, meth.split(":")[0...-1].join(":")] + + files = thor_yaml.select do |_, v| + v[:namespaces] && !(v[:namespaces] & lookup).empty? + end + + files.map { |_, v| File.join(thor_root, (v[:filename]).to_s) } + end + + # Display information about the given klasses. If with_module is given, + # it shows a table with information extracted from the yaml file. + # + def display_klasses(with_modules = false, show_internal = false, klasses = Bundler::Thor::Base.subclasses) + klasses -= [Bundler::Thor, Bundler::Thor::Runner, Bundler::Thor::Group] unless show_internal + + raise Error, "No Bundler::Thor commands available" if klasses.empty? + show_modules if with_modules && !thor_yaml.empty? + + list = Hash.new { |h, k| h[k] = [] } + groups = klasses.select { |k| k.ancestors.include?(Bundler::Thor::Group) } + + # Get classes which inherit from Bundler::Thor + (klasses - groups).each { |k| list[k.namespace.split(":").first] += k.printable_commands(false) } + + # Get classes which inherit from Bundler::Thor::Base + groups.map! { |k| k.printable_commands(false).first } + list["root"] = groups + + # Order namespaces with default coming first + list = list.sort { |a, b| a[0].sub(/^default/, "") <=> b[0].sub(/^default/, "") } + list.each { |n, commands| display_commands(n, commands) unless commands.empty? } + end + + def display_commands(namespace, list) #:nodoc: + list.sort! { |a, b| a[0] <=> b[0] } + + say shell.set_color(namespace, :blue, true) + say "-" * namespace.size + + print_table(list, :truncate => true) + say + end + alias_method :display_tasks, :display_commands + + def show_modules #:nodoc: + info = [] + labels = %w(Modules Namespaces) + + info << labels + info << ["-" * labels[0].size, "-" * labels[1].size] + + thor_yaml.each do |name, hash| + info << [name, hash[:namespaces].join(", ")] + end + + print_table info + say "" + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/shell.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/shell.rb new file mode 100644 index 0000000..a4137d1 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/shell.rb @@ -0,0 +1,81 @@ +require "rbconfig" + +class Bundler::Thor + module Base + class << self + attr_writer :shell + + # Returns the shell used in all Bundler::Thor classes. If you are in a Unix platform + # it will use a colored log, otherwise it will use a basic one without color. + # + def shell + @shell ||= if ENV["THOR_SHELL"] && !ENV["THOR_SHELL"].empty? + Bundler::Thor::Shell.const_get(ENV["THOR_SHELL"]) + elsif RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ && !ENV["ANSICON"] + Bundler::Thor::Shell::Basic + else + Bundler::Thor::Shell::Color + end + end + end + end + + module Shell + SHELL_DELEGATED_METHODS = [:ask, :error, :set_color, :yes?, :no?, :say, :say_error, :say_status, :print_in_columns, :print_table, :print_wrapped, :file_collision, :terminal_width] + attr_writer :shell + + autoload :Basic, File.expand_path("shell/basic", __dir__) + autoload :Color, File.expand_path("shell/color", __dir__) + autoload :HTML, File.expand_path("shell/html", __dir__) + + # Add shell to initialize config values. + # + # ==== Configuration + # shell:: An instance of the shell to be used. + # + # ==== Examples + # + # class MyScript < Bundler::Thor + # argument :first, :type => :numeric + # end + # + # MyScript.new [1.0], { :foo => :bar }, :shell => Bundler::Thor::Shell::Basic.new + # + def initialize(args = [], options = {}, config = {}) + super + self.shell = config[:shell] + shell.base ||= self if shell.respond_to?(:base) + end + + # Holds the shell for the given Bundler::Thor instance. If no shell is given, + # it gets a default shell from Bundler::Thor::Base.shell. + def shell + @shell ||= Bundler::Thor::Base.shell.new + end + + # Common methods that are delegated to the shell. + SHELL_DELEGATED_METHODS.each do |method| + module_eval <<-METHOD, __FILE__, __LINE__ + 1 + def #{method}(*args,&block) + shell.#{method}(*args,&block) + end + METHOD + end + + # Yields the given block with padding. + def with_padding + shell.padding += 1 + yield + ensure + shell.padding -= 1 + end + + protected + + # Allow shell to be shared between invocations. + # + def _shared_configuration #:nodoc: + super.merge!(:shell => shell) + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/shell/basic.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/shell/basic.rb new file mode 100644 index 0000000..8eff00b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/shell/basic.rb @@ -0,0 +1,512 @@ +class Bundler::Thor + module Shell + class Basic + DEFAULT_TERMINAL_WIDTH = 80 + + attr_accessor :base + attr_reader :padding + + # Initialize base, mute and padding to nil. + # + def initialize #:nodoc: + @base = nil + @mute = false + @padding = 0 + @always_force = false + end + + # Mute everything that's inside given block + # + def mute + @mute = true + yield + ensure + @mute = false + end + + # Check if base is muted + # + def mute? + @mute + end + + # Sets the output padding, not allowing less than zero values. + # + def padding=(value) + @padding = [0, value].max + end + + # Sets the output padding while executing a block and resets it. + # + def indent(count = 1) + orig_padding = padding + self.padding = padding + count + yield + self.padding = orig_padding + end + + # Asks something to the user and receives a response. + # + # If a default value is specified it will be presented to the user + # and allows them to select that value with an empty response. This + # option is ignored when limited answers are supplied. + # + # If asked to limit the correct responses, you can pass in an + # array of acceptable answers. If one of those is not supplied, + # they will be shown a message stating that one of those answers + # must be given and re-asked the question. + # + # If asking for sensitive information, the :echo option can be set + # to false to mask user input from $stdin. + # + # If the required input is a path, then set the path option to + # true. This will enable tab completion for file paths relative + # to the current working directory on systems that support + # Readline. + # + # ==== Example + # ask("What is your name?") + # + # ask("What is the planet furthest from the sun?", :default => "Pluto") + # + # ask("What is your favorite Neopolitan flavor?", :limited_to => ["strawberry", "chocolate", "vanilla"]) + # + # ask("What is your password?", :echo => false) + # + # ask("Where should the file be saved?", :path => true) + # + def ask(statement, *args) + options = args.last.is_a?(Hash) ? args.pop : {} + color = args.first + + if options[:limited_to] + ask_filtered(statement, color, options) + else + ask_simply(statement, color, options) + end + end + + # Say (print) something to the user. If the sentence ends with a whitespace + # or tab character, a new line is not appended (print + flush). Otherwise + # are passed straight to puts (behavior got from Highline). + # + # ==== Example + # say("I know you knew that.") + # + def say(message = "", color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/)) + return if quiet? + + buffer = prepare_message(message, *color) + buffer << "\n" if force_new_line && !message.to_s.end_with?("\n") + + stdout.print(buffer) + stdout.flush + end + + # Say (print) an error to the user. If the sentence ends with a whitespace + # or tab character, a new line is not appended (print + flush). Otherwise + # are passed straight to puts (behavior got from Highline). + # + # ==== Example + # say_error("error: something went wrong") + # + def say_error(message = "", color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/)) + return if quiet? + + buffer = prepare_message(message, *color) + buffer << "\n" if force_new_line && !message.to_s.end_with?("\n") + + stderr.print(buffer) + stderr.flush + end + + # Say a status with the given color and appends the message. Since this + # method is used frequently by actions, it allows nil or false to be given + # in log_status, avoiding the message from being shown. If a Symbol is + # given in log_status, it's used as the color. + # + def say_status(status, message, log_status = true) + return if quiet? || log_status == false + spaces = " " * (padding + 1) + status = status.to_s.rjust(12) + margin = " " * status.length + spaces + + color = log_status.is_a?(Symbol) ? log_status : :green + status = set_color status, color, true if color + + message = message.to_s.chomp.gsub(/(? false) =~ is?(:yes)) + end + + # Make a question the to user and returns true if the user replies "n" or + # "no". + # + def no?(statement, color = nil) + !!(ask(statement, color, :add_to_history => false) =~ is?(:no)) + end + + # Prints values in columns + # + # ==== Parameters + # Array[String, String, ...] + # + def print_in_columns(array) + return if array.empty? + colwidth = (array.map { |el| el.to_s.size }.max || 0) + 2 + array.each_with_index do |value, index| + # Don't output trailing spaces when printing the last column + if ((((index + 1) % (terminal_width / colwidth))).zero? && !index.zero?) || index + 1 == array.length + stdout.puts value + else + stdout.printf("%-#{colwidth}s", value) + end + end + end + + # Prints a table. + # + # ==== Parameters + # Array[Array[String, String, ...]] + # + # ==== Options + # indent:: Indent the first column by indent value. + # colwidth:: Force the first column to colwidth spaces wide. + # + def print_table(array, options = {}) # rubocop:disable MethodLength + return if array.empty? + + formats = [] + indent = options[:indent].to_i + colwidth = options[:colwidth] + options[:truncate] = terminal_width if options[:truncate] == true + + formats << "%-#{colwidth + 2}s".dup if colwidth + start = colwidth ? 1 : 0 + + colcount = array.max { |a, b| a.size <=> b.size }.size + + maximas = [] + + start.upto(colcount - 1) do |index| + maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max + maximas << maxima + formats << if index == colcount - 1 + # Don't output 2 trailing spaces when printing the last column + "%-s".dup + else + "%-#{maxima + 2}s".dup + end + end + + formats[0] = formats[0].insert(0, " " * indent) + formats << "%s" + + array.each do |row| + sentence = "".dup + + row.each_with_index do |column, index| + maxima = maximas[index] + + f = if column.is_a?(Numeric) + if index == row.size - 1 + # Don't output 2 trailing spaces when printing the last column + "%#{maxima}s" + else + "%#{maxima}s " + end + else + formats[index] + end + sentence << f % column.to_s + end + + sentence = truncate(sentence, options[:truncate]) if options[:truncate] + stdout.puts sentence + end + end + + # Prints a long string, word-wrapping the text to the current width of the + # terminal display. Ideal for printing heredocs. + # + # ==== Parameters + # String + # + # ==== Options + # indent:: Indent each line of the printed paragraph by indent value. + # + def print_wrapped(message, options = {}) + indent = options[:indent] || 0 + width = terminal_width - indent + paras = message.split("\n\n") + + paras.map! do |unwrapped| + words = unwrapped.split(" ") + counter = words.first.length + words.inject do |memo, word| + word = word.gsub(/\n\005/, "\n").gsub(/\005/, "\n") + counter = 0 if word.include? "\n" + if (counter + word.length + 1) < width + memo = "#{memo} #{word}" + counter += (word.length + 1) + else + memo = "#{memo}\n#{word}" + counter = word.length + end + memo + end + end.compact! + + paras.each do |para| + para.split("\n").each do |line| + stdout.puts line.insert(0, " " * indent) + end + stdout.puts unless para == paras.last + end + end + + # Deals with file collision and returns true if the file should be + # overwritten and false otherwise. If a block is given, it uses the block + # response as the content for the diff. + # + # ==== Parameters + # destination:: the destination file to solve conflicts + # block:: an optional block that returns the value to be used in diff and merge + # + def file_collision(destination) + return true if @always_force + options = block_given? ? "[Ynaqdhm]" : "[Ynaqh]" + + loop do + answer = ask( + %[Overwrite #{destination}? (enter "h" for help) #{options}], + :add_to_history => false + ) + + case answer + when nil + say "" + return true + when is?(:yes), is?(:force), "" + return true + when is?(:no), is?(:skip) + return false + when is?(:always) + return @always_force = true + when is?(:quit) + say "Aborting..." + raise SystemExit + when is?(:diff) + show_diff(destination, yield) if block_given? + say "Retrying..." + when is?(:merge) + if block_given? && !merge_tool.empty? + merge(destination, yield) + return nil + end + + say "Please specify merge tool to `THOR_MERGE` env." + else + say file_collision_help + end + end + end + + # This code was copied from Rake, available under MIT-LICENSE + # Copyright (c) 2003, 2004 Jim Weirich + def terminal_width + result = if ENV["THOR_COLUMNS"] + ENV["THOR_COLUMNS"].to_i + else + unix? ? dynamic_width : DEFAULT_TERMINAL_WIDTH + end + result < 10 ? DEFAULT_TERMINAL_WIDTH : result + rescue + DEFAULT_TERMINAL_WIDTH + end + + # Called if something goes wrong during the execution. This is used by Bundler::Thor + # internally and should not be used inside your scripts. If something went + # wrong, you can always raise an exception. If you raise a Bundler::Thor::Error, it + # will be rescued and wrapped in the method below. + # + def error(statement) + stderr.puts statement + end + + # Apply color to the given string with optional bold. Disabled in the + # Bundler::Thor::Shell::Basic class. + # + def set_color(string, *) #:nodoc: + string + end + + protected + + def prepare_message(message, *color) + spaces = " " * padding + spaces + set_color(message.to_s, *color) + end + + def can_display_colors? + false + end + + def lookup_color(color) + return color unless color.is_a?(Symbol) + self.class.const_get(color.to_s.upcase) + end + + def stdout + $stdout + end + + def stderr + $stderr + end + + def is?(value) #:nodoc: + value = value.to_s + + if value.size == 1 + /\A#{value}\z/i + else + /\A(#{value}|#{value[0, 1]})\z/i + end + end + + def file_collision_help #:nodoc: + <<-HELP + Y - yes, overwrite + n - no, do not overwrite + a - all, overwrite this and all others + q - quit, abort + d - diff, show the differences between the old and the new + h - help, show this help + m - merge, run merge tool + HELP + end + + def show_diff(destination, content) #:nodoc: + diff_cmd = ENV["THOR_DIFF"] || ENV["RAILS_DIFF"] || "diff -u" + + require "tempfile" + Tempfile.open(File.basename(destination), File.dirname(destination)) do |temp| + temp.write content + temp.rewind + system %(#{diff_cmd} "#{destination}" "#{temp.path}") + end + end + + def quiet? #:nodoc: + mute? || (base && base.options[:quiet]) + end + + # Calculate the dynamic width of the terminal + def dynamic_width + @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput) + end + + def dynamic_width_stty + `stty size 2>/dev/null`.split[1].to_i + end + + def dynamic_width_tput + `tput cols 2>/dev/null`.to_i + end + + def unix? + RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i + end + + def truncate(string, width) + as_unicode do + chars = string.chars.to_a + if chars.length <= width + chars.join + else + chars[0, width - 3].join + "..." + end + end + end + + if "".respond_to?(:encode) + def as_unicode + yield + end + else + def as_unicode + old = $KCODE + $KCODE = "U" + yield + ensure + $KCODE = old + end + end + + def ask_simply(statement, color, options) + default = options[:default] + message = [statement, ("(#{default})" if default), nil].uniq.join(" ") + message = prepare_message(message, *color) + result = Bundler::Thor::LineEditor.readline(message, options) + + return unless result + + result = result.strip + + if default && result == "" + default + else + result + end + end + + def ask_filtered(statement, color, options) + answer_set = options[:limited_to] + case_insensitive = options.fetch(:case_insensitive, false) + correct_answer = nil + until correct_answer + answers = answer_set.join(", ") + answer = ask_simply("#{statement} [#{answers}]", color, options) + correct_answer = answer_match(answer_set, answer, case_insensitive) + say("Your response must be one of: [#{answers}]. Please try again.") unless correct_answer + end + correct_answer + end + + def answer_match(possibilities, answer, case_insensitive) + if case_insensitive + possibilities.detect{ |possibility| possibility.downcase == answer.downcase } + else + possibilities.detect{ |possibility| possibility == answer } + end + end + + def merge(destination, content) #:nodoc: + require "tempfile" + Tempfile.open([File.basename(destination), File.extname(destination)], File.dirname(destination)) do |temp| + temp.write content + temp.rewind + system %(#{merge_tool} "#{temp.path}" "#{destination}") + end + end + + def merge_tool #:nodoc: + @merge_tool ||= ENV["THOR_MERGE"] || git_merge_tool + end + + def git_merge_tool #:nodoc: + `git config merge.tool`.rstrip rescue "" + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/shell/color.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/shell/color.rb new file mode 100644 index 0000000..dc167ed --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/shell/color.rb @@ -0,0 +1,157 @@ +require_relative "basic" + +class Bundler::Thor + module Shell + # Inherit from Bundler::Thor::Shell::Basic and add set_color behavior. Check + # Bundler::Thor::Shell::Basic to see all available methods. + # + class Color < Basic + # Embed in a String to clear all previous ANSI sequences. + CLEAR = "\e[0m" + # The start of an ANSI bold sequence. + BOLD = "\e[1m" + + # Set the terminal's foreground ANSI color to black. + BLACK = "\e[30m" + # Set the terminal's foreground ANSI color to red. + RED = "\e[31m" + # Set the terminal's foreground ANSI color to green. + GREEN = "\e[32m" + # Set the terminal's foreground ANSI color to yellow. + YELLOW = "\e[33m" + # Set the terminal's foreground ANSI color to blue. + BLUE = "\e[34m" + # Set the terminal's foreground ANSI color to magenta. + MAGENTA = "\e[35m" + # Set the terminal's foreground ANSI color to cyan. + CYAN = "\e[36m" + # Set the terminal's foreground ANSI color to white. + WHITE = "\e[37m" + + # Set the terminal's background ANSI color to black. + ON_BLACK = "\e[40m" + # Set the terminal's background ANSI color to red. + ON_RED = "\e[41m" + # Set the terminal's background ANSI color to green. + ON_GREEN = "\e[42m" + # Set the terminal's background ANSI color to yellow. + ON_YELLOW = "\e[43m" + # Set the terminal's background ANSI color to blue. + ON_BLUE = "\e[44m" + # Set the terminal's background ANSI color to magenta. + ON_MAGENTA = "\e[45m" + # Set the terminal's background ANSI color to cyan. + ON_CYAN = "\e[46m" + # Set the terminal's background ANSI color to white. + ON_WHITE = "\e[47m" + + # Set color by using a string or one of the defined constants. If a third + # option is set to true, it also adds bold to the string. This is based + # on Highline implementation and it automatically appends CLEAR to the end + # of the returned String. + # + # Pass foreground, background and bold options to this method as + # symbols. + # + # Example: + # + # set_color "Hi!", :red, :on_white, :bold + # + # The available colors are: + # + # :bold + # :black + # :red + # :green + # :yellow + # :blue + # :magenta + # :cyan + # :white + # :on_black + # :on_red + # :on_green + # :on_yellow + # :on_blue + # :on_magenta + # :on_cyan + # :on_white + def set_color(string, *colors) + if colors.compact.empty? || !can_display_colors? + string + elsif colors.all? { |color| color.is_a?(Symbol) || color.is_a?(String) } + ansi_colors = colors.map { |color| lookup_color(color) } + "#{ansi_colors.join}#{string}#{CLEAR}" + else + # The old API was `set_color(color, bold=boolean)`. We + # continue to support the old API because you should never + # break old APIs unnecessarily :P + foreground, bold = colors + foreground = self.class.const_get(foreground.to_s.upcase) if foreground.is_a?(Symbol) + + bold = bold ? BOLD : "" + "#{bold}#{foreground}#{string}#{CLEAR}" + end + end + + protected + + def can_display_colors? + are_colors_supported? && !are_colors_disabled? + end + + def are_colors_supported? + stdout.tty? && ENV["TERM"] != "dumb" + end + + def are_colors_disabled? + !ENV['NO_COLOR'].nil? + end + + # Overwrite show_diff to show diff with colors if Diff::LCS is + # available. + # + def show_diff(destination, content) #:nodoc: + if diff_lcs_loaded? && ENV["THOR_DIFF"].nil? && ENV["RAILS_DIFF"].nil? + actual = File.binread(destination).to_s.split("\n") + content = content.to_s.split("\n") + + Diff::LCS.sdiff(actual, content).each do |diff| + output_diff_line(diff) + end + else + super + end + end + + def output_diff_line(diff) #:nodoc: + case diff.action + when "-" + say "- #{diff.old_element.chomp}", :red, true + when "+" + say "+ #{diff.new_element.chomp}", :green, true + when "!" + say "- #{diff.old_element.chomp}", :red, true + say "+ #{diff.new_element.chomp}", :green, true + else + say " #{diff.old_element.chomp}", nil, true + end + end + + # Check if Diff::LCS is loaded. If it is, use it to create pretty output + # for diff. + # + def diff_lcs_loaded? #:nodoc: + return true if defined?(Diff::LCS) + return @diff_lcs_loaded unless @diff_lcs_loaded.nil? + + @diff_lcs_loaded = begin + require "diff/lcs" + true + rescue LoadError + false + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/shell/html.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/shell/html.rb new file mode 100644 index 0000000..77a6d13 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/shell/html.rb @@ -0,0 +1,126 @@ +require_relative "basic" + +class Bundler::Thor + module Shell + # Inherit from Bundler::Thor::Shell::Basic and add set_color behavior. Check + # Bundler::Thor::Shell::Basic to see all available methods. + # + class HTML < Basic + # The start of an HTML bold sequence. + BOLD = "font-weight: bold" + + # Set the terminal's foreground HTML color to black. + BLACK = "color: black" + # Set the terminal's foreground HTML color to red. + RED = "color: red" + # Set the terminal's foreground HTML color to green. + GREEN = "color: green" + # Set the terminal's foreground HTML color to yellow. + YELLOW = "color: yellow" + # Set the terminal's foreground HTML color to blue. + BLUE = "color: blue" + # Set the terminal's foreground HTML color to magenta. + MAGENTA = "color: magenta" + # Set the terminal's foreground HTML color to cyan. + CYAN = "color: cyan" + # Set the terminal's foreground HTML color to white. + WHITE = "color: white" + + # Set the terminal's background HTML color to black. + ON_BLACK = "background-color: black" + # Set the terminal's background HTML color to red. + ON_RED = "background-color: red" + # Set the terminal's background HTML color to green. + ON_GREEN = "background-color: green" + # Set the terminal's background HTML color to yellow. + ON_YELLOW = "background-color: yellow" + # Set the terminal's background HTML color to blue. + ON_BLUE = "background-color: blue" + # Set the terminal's background HTML color to magenta. + ON_MAGENTA = "background-color: magenta" + # Set the terminal's background HTML color to cyan. + ON_CYAN = "background-color: cyan" + # Set the terminal's background HTML color to white. + ON_WHITE = "background-color: white" + + # Set color by using a string or one of the defined constants. If a third + # option is set to true, it also adds bold to the string. This is based + # on Highline implementation and it automatically appends CLEAR to the end + # of the returned String. + # + def set_color(string, *colors) + if colors.all? { |color| color.is_a?(Symbol) || color.is_a?(String) } + html_colors = colors.map { |color| lookup_color(color) } + "#{Bundler::Thor::Util.escape_html(string)}" + else + color, bold = colors + html_color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol) + styles = [html_color] + styles << BOLD if bold + "#{Bundler::Thor::Util.escape_html(string)}" + end + end + + # Ask something to the user and receives a response. + # + # ==== Example + # ask("What is your name?") + # + # TODO: Implement #ask for Bundler::Thor::Shell::HTML + def ask(statement, color = nil) + raise NotImplementedError, "Implement #ask for Bundler::Thor::Shell::HTML" + end + + protected + + def can_display_colors? + true + end + + # Overwrite show_diff to show diff with colors if Diff::LCS is + # available. + # + def show_diff(destination, content) #:nodoc: + if diff_lcs_loaded? && ENV["THOR_DIFF"].nil? && ENV["RAILS_DIFF"].nil? + actual = File.binread(destination).to_s.split("\n") + content = content.to_s.split("\n") + + Diff::LCS.sdiff(actual, content).each do |diff| + output_diff_line(diff) + end + else + super + end + end + + def output_diff_line(diff) #:nodoc: + case diff.action + when "-" + say "- #{diff.old_element.chomp}", :red, true + when "+" + say "+ #{diff.new_element.chomp}", :green, true + when "!" + say "- #{diff.old_element.chomp}", :red, true + say "+ #{diff.new_element.chomp}", :green, true + else + say " #{diff.old_element.chomp}", nil, true + end + end + + # Check if Diff::LCS is loaded. If it is, use it to create pretty output + # for diff. + # + def diff_lcs_loaded? #:nodoc: + return true if defined?(Diff::LCS) + return @diff_lcs_loaded unless @diff_lcs_loaded.nil? + + @diff_lcs_loaded = begin + require "diff/lcs" + true + rescue LoadError + false + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/util.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/util.rb new file mode 100644 index 0000000..d2572a4 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/util.rb @@ -0,0 +1,284 @@ +require "rbconfig" + +class Bundler::Thor + module Sandbox #:nodoc: + end + + # This module holds several utilities: + # + # 1) Methods to convert thor namespaces to constants and vice-versa. + # + # Bundler::Thor::Util.namespace_from_thor_class(Foo::Bar::Baz) #=> "foo:bar:baz" + # + # 2) Loading thor files and sandboxing: + # + # Bundler::Thor::Util.load_thorfile("~/.thor/foo") + # + module Util + class << self + # Receives a namespace and search for it in the Bundler::Thor::Base subclasses. + # + # ==== Parameters + # namespace:: The namespace to search for. + # + def find_by_namespace(namespace) + namespace = "default#{namespace}" if namespace.empty? || namespace =~ /^:/ + Bundler::Thor::Base.subclasses.detect { |klass| klass.namespace == namespace } + end + + # Receives a constant and converts it to a Bundler::Thor namespace. Since Bundler::Thor + # commands can be added to a sandbox, this method is also responsible for + # removing the sandbox namespace. + # + # This method should not be used in general because it's used to deal with + # older versions of Bundler::Thor. On current versions, if you need to get the + # namespace from a class, just call namespace on it. + # + # ==== Parameters + # constant:: The constant to be converted to the thor path. + # + # ==== Returns + # String:: If we receive Foo::Bar::Baz it returns "foo:bar:baz" + # + def namespace_from_thor_class(constant) + constant = constant.to_s.gsub(/^Bundler::Thor::Sandbox::/, "") + constant = snake_case(constant).squeeze(":") + constant + end + + # Given the contents, evaluate it inside the sandbox and returns the + # namespaces defined in the sandbox. + # + # ==== Parameters + # contents + # + # ==== Returns + # Array[Object] + # + def namespaces_in_content(contents, file = __FILE__) + old_constants = Bundler::Thor::Base.subclasses.dup + Bundler::Thor::Base.subclasses.clear + + load_thorfile(file, contents) + + new_constants = Bundler::Thor::Base.subclasses.dup + Bundler::Thor::Base.subclasses.replace(old_constants) + + new_constants.map!(&:namespace) + new_constants.compact! + new_constants + end + + # Returns the thor classes declared inside the given class. + # + def thor_classes_in(klass) + stringfied_constants = klass.constants.map(&:to_s) + Bundler::Thor::Base.subclasses.select do |subclass| + next unless subclass.name + stringfied_constants.include?(subclass.name.gsub("#{klass.name}::", "")) + end + end + + # Receives a string and convert it to snake case. SnakeCase returns snake_case. + # + # ==== Parameters + # String + # + # ==== Returns + # String + # + def snake_case(str) + return str.downcase if str =~ /^[A-Z_]+$/ + str.gsub(/\B[A-Z]/, '_\&').squeeze("_") =~ /_*(.*)/ + $+.downcase + end + + # Receives a string and convert it to camel case. camel_case returns CamelCase. + # + # ==== Parameters + # String + # + # ==== Returns + # String + # + def camel_case(str) + return str if str !~ /_/ && str =~ /[A-Z]+.*/ + str.split("_").map(&:capitalize).join + end + + # Receives a namespace and tries to retrieve a Bundler::Thor or Bundler::Thor::Group class + # from it. It first searches for a class using the all the given namespace, + # if it's not found, removes the highest entry and searches for the class + # again. If found, returns the highest entry as the class name. + # + # ==== Examples + # + # class Foo::Bar < Bundler::Thor + # def baz + # end + # end + # + # class Baz::Foo < Bundler::Thor::Group + # end + # + # Bundler::Thor::Util.namespace_to_thor_class("foo:bar") #=> Foo::Bar, nil # will invoke default command + # Bundler::Thor::Util.namespace_to_thor_class("baz:foo") #=> Baz::Foo, nil + # Bundler::Thor::Util.namespace_to_thor_class("foo:bar:baz") #=> Foo::Bar, "baz" + # + # ==== Parameters + # namespace + # + def find_class_and_command_by_namespace(namespace, fallback = true) + if namespace.include?(":") # look for a namespaced command + pieces = namespace.split(":") + command = pieces.pop + klass = Bundler::Thor::Util.find_by_namespace(pieces.join(":")) + end + unless klass # look for a Bundler::Thor::Group with the right name + klass = Bundler::Thor::Util.find_by_namespace(namespace) + command = nil + end + if !klass && fallback # try a command in the default namespace + command = namespace + klass = Bundler::Thor::Util.find_by_namespace("") + end + [klass, command] + end + alias_method :find_class_and_task_by_namespace, :find_class_and_command_by_namespace + + # Receives a path and load the thor file in the path. The file is evaluated + # inside the sandbox to avoid namespacing conflicts. + # + def load_thorfile(path, content = nil, debug = false) + content ||= File.binread(path) + + begin + Bundler::Thor::Sandbox.class_eval(content, path) + rescue StandardError => e + $stderr.puts("WARNING: unable to load thorfile #{path.inspect}: #{e.message}") + if debug + $stderr.puts(*e.backtrace) + else + $stderr.puts(e.backtrace.first) + end + end + end + + def user_home + @@user_home ||= if ENV["HOME"] + ENV["HOME"] + elsif ENV["USERPROFILE"] + ENV["USERPROFILE"] + elsif ENV["HOMEDRIVE"] && ENV["HOMEPATH"] + File.join(ENV["HOMEDRIVE"], ENV["HOMEPATH"]) + elsif ENV["APPDATA"] + ENV["APPDATA"] + else + begin + File.expand_path("~") + rescue + if File::ALT_SEPARATOR + "C:/" + else + "/" + end + end + end + end + + # Returns the root where thor files are located, depending on the OS. + # + def thor_root + File.join(user_home, ".thor").tr('\\', "/") + end + + # Returns the files in the thor root. On Windows thor_root will be something + # like this: + # + # C:\Documents and Settings\james\.thor + # + # If we don't #gsub the \ character, Dir.glob will fail. + # + def thor_root_glob + files = Dir["#{escape_globs(thor_root)}/*"] + + files.map! do |file| + File.directory?(file) ? File.join(file, "main.thor") : file + end + end + + # Where to look for Bundler::Thor files. + # + def globs_for(path) + path = escape_globs(path) + ["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/**/*.thor"] + end + + # Return the path to the ruby interpreter taking into account multiple + # installations and windows extensions. + # + def ruby_command + @ruby_command ||= begin + ruby_name = RbConfig::CONFIG["ruby_install_name"] + ruby = File.join(RbConfig::CONFIG["bindir"], ruby_name) + ruby << RbConfig::CONFIG["EXEEXT"] + + # avoid using different name than ruby (on platforms supporting links) + if ruby_name != "ruby" && File.respond_to?(:readlink) + begin + alternate_ruby = File.join(RbConfig::CONFIG["bindir"], "ruby") + alternate_ruby << RbConfig::CONFIG["EXEEXT"] + + # ruby is a symlink + if File.symlink? alternate_ruby + linked_ruby = File.readlink alternate_ruby + + # symlink points to 'ruby_install_name' + ruby = alternate_ruby if linked_ruby == ruby_name || linked_ruby == ruby + end + rescue NotImplementedError # rubocop:disable HandleExceptions + # just ignore on windows + end + end + + # escape string in case path to ruby executable contain spaces. + ruby.sub!(/.*\s.*/m, '"\&"') + ruby + end + end + + # Returns a string that has had any glob characters escaped. + # The glob characters are `* ? { } [ ]`. + # + # ==== Examples + # + # Bundler::Thor::Util.escape_globs('[apps]') # => '\[apps\]' + # + # ==== Parameters + # String + # + # ==== Returns + # String + # + def escape_globs(path) + path.to_s.gsub(/[*?{}\[\]]/, '\\\\\\&') + end + + # Returns a string that has had any HTML characters escaped. + # + # ==== Examples + # + # Bundler::Thor::Util.escape_html('
    ') # => "<div>" + # + # ==== Parameters + # String + # + # ==== Returns + # String + # + def escape_html(string) + CGI.escapeHTML(string) + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/version.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/version.rb new file mode 100644 index 0000000..48a4788 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/thor/lib/thor/version.rb @@ -0,0 +1,3 @@ +class Bundler::Thor + VERSION = "1.2.1" +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/tmpdir/lib/tmpdir.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/tmpdir/lib/tmpdir.rb new file mode 100644 index 0000000..70d43e0 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/tmpdir/lib/tmpdir.rb @@ -0,0 +1,154 @@ +# frozen_string_literal: true +# +# tmpdir - retrieve temporary directory path +# +# $Id$ +# + +require_relative '../../fileutils/lib/fileutils' +begin + require 'etc.so' +rescue LoadError # rescue LoadError for miniruby +end + +class Bundler::Dir < Dir + + @systmpdir ||= defined?(Etc.systmpdir) ? Etc.systmpdir : '/tmp' + + ## + # Returns the operating system's temporary file path. + + def self.tmpdir + tmp = nil + ['TMPDIR', 'TMP', 'TEMP', ['system temporary path', @systmpdir], ['/tmp']*2, ['.']*2].each do |name, dir = ENV[name]| + next if !dir + dir = File.expand_path(dir) + stat = File.stat(dir) rescue next + case + when !stat.directory? + warn "#{name} is not a directory: #{dir}" + when !stat.writable? + warn "#{name} is not writable: #{dir}" + when stat.world_writable? && !stat.sticky? + warn "#{name} is world-writable: #{dir}" + else + tmp = dir + break + end + end + raise ArgumentError, "could not find a temporary directory" unless tmp + tmp + end + + # Bundler::Dir.mktmpdir creates a temporary directory. + # + # The directory is created with 0700 permission. + # Application should not change the permission to make the temporary directory accessible from other users. + # + # The prefix and suffix of the name of the directory is specified by + # the optional first argument, prefix_suffix. + # - If it is not specified or nil, "d" is used as the prefix and no suffix is used. + # - If it is a string, it is used as the prefix and no suffix is used. + # - If it is an array, first element is used as the prefix and second element is used as a suffix. + # + # Bundler::Dir.mktmpdir {|dir| dir is ".../d..." } + # Bundler::Dir.mktmpdir("foo") {|dir| dir is ".../foo..." } + # Bundler::Dir.mktmpdir(["foo", "bar"]) {|dir| dir is ".../foo...bar" } + # + # The directory is created under Bundler::Dir.tmpdir or + # the optional second argument tmpdir if non-nil value is given. + # + # Bundler::Dir.mktmpdir {|dir| dir is "#{Bundler::Dir.tmpdir}/d..." } + # Bundler::Dir.mktmpdir(nil, "/var/tmp") {|dir| dir is "/var/tmp/d..." } + # + # If a block is given, + # it is yielded with the path of the directory. + # The directory and its contents are removed + # using Bundler::FileUtils.remove_entry before Bundler::Dir.mktmpdir returns. + # The value of the block is returned. + # + # Bundler::Dir.mktmpdir {|dir| + # # use the directory... + # open("#{dir}/foo", "w") { ... } + # } + # + # If a block is not given, + # The path of the directory is returned. + # In this case, Bundler::Dir.mktmpdir doesn't remove the directory. + # + # dir = Bundler::Dir.mktmpdir + # begin + # # use the directory... + # open("#{dir}/foo", "w") { ... } + # ensure + # # remove the directory. + # Bundler::FileUtils.remove_entry dir + # end + # + def self.mktmpdir(prefix_suffix=nil, *rest, **options) + base = nil + path = Tmpname.create(prefix_suffix || "d", *rest, **options) {|p, _, _, d| + base = d + mkdir(p, 0700) + } + if block_given? + begin + yield path.dup + ensure + unless base + stat = File.stat(File.dirname(path)) + if stat.world_writable? and !stat.sticky? + raise ArgumentError, "parent directory is world writable but not sticky" + end + end + Bundler::FileUtils.remove_entry path + end + else + path + end + end + + module Tmpname # :nodoc: + module_function + + def tmpdir + Bundler::Dir.tmpdir + end + + UNUSABLE_CHARS = "^,-.0-9A-Z_a-z~" + + class << (RANDOM = Random.new) + MAX = 36**6 # < 0x100000000 + def next + rand(MAX).to_s(36) + end + end + private_constant :RANDOM + + def create(basename, tmpdir=nil, max_try: nil, **opts) + origdir = tmpdir + tmpdir ||= tmpdir() + n = nil + prefix, suffix = basename + prefix = (String.try_convert(prefix) or + raise ArgumentError, "unexpected prefix: #{prefix.inspect}") + prefix = prefix.delete(UNUSABLE_CHARS) + suffix &&= (String.try_convert(suffix) or + raise ArgumentError, "unexpected suffix: #{suffix.inspect}") + suffix &&= suffix.delete(UNUSABLE_CHARS) + begin + t = Time.now.strftime("%Y%m%d") + path = "#{prefix}#{t}-#{$$}-#{RANDOM.next}"\ + "#{n ? %[-#{n}] : ''}#{suffix||''}" + path = File.join(tmpdir, path) + yield(path, n, opts, origdir) + rescue Errno::EEXIST + n ||= 0 + n += 1 + retry if !max_try or n < max_try + raise "cannot generate temporary name using `#{basename}' under `#{tmpdir}'" + end + path + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/tsort/lib/tsort.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/tsort/lib/tsort.rb new file mode 100644 index 0000000..4a0e1a4 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/tsort/lib/tsort.rb @@ -0,0 +1,452 @@ +# frozen_string_literal: true + +#-- +# tsort.rb - provides a module for topological sorting and strongly connected components. +#++ +# + +# +# Bundler::TSort implements topological sorting using Tarjan's algorithm for +# strongly connected components. +# +# Bundler::TSort is designed to be able to be used with any object which can be +# interpreted as a directed graph. +# +# Bundler::TSort requires two methods to interpret an object as a graph, +# tsort_each_node and tsort_each_child. +# +# * tsort_each_node is used to iterate for all nodes over a graph. +# * tsort_each_child is used to iterate for child nodes of a given node. +# +# The equality of nodes are defined by eql? and hash since +# Bundler::TSort uses Hash internally. +# +# == A Simple Example +# +# The following example demonstrates how to mix the Bundler::TSort module into an +# existing class (in this case, Hash). Here, we're treating each key in +# the hash as a node in the graph, and so we simply alias the required +# #tsort_each_node method to Hash's #each_key method. For each key in the +# hash, the associated value is an array of the node's child nodes. This +# choice in turn leads to our implementation of the required #tsort_each_child +# method, which fetches the array of child nodes and then iterates over that +# array using the user-supplied block. +# +# require 'bundler/vendor/tsort/lib/tsort' +# +# class Hash +# include Bundler::TSort +# alias tsort_each_node each_key +# def tsort_each_child(node, &block) +# fetch(node).each(&block) +# end +# end +# +# {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort +# #=> [3, 2, 1, 4] +# +# {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components +# #=> [[4], [2, 3], [1]] +# +# == A More Realistic Example +# +# A very simple `make' like tool can be implemented as follows: +# +# require 'bundler/vendor/tsort/lib/tsort' +# +# class Make +# def initialize +# @dep = {} +# @dep.default = [] +# end +# +# def rule(outputs, inputs=[], &block) +# triple = [outputs, inputs, block] +# outputs.each {|f| @dep[f] = [triple]} +# @dep[triple] = inputs +# end +# +# def build(target) +# each_strongly_connected_component_from(target) {|ns| +# if ns.length != 1 +# fs = ns.delete_if {|n| Array === n} +# raise Bundler::TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}") +# end +# n = ns.first +# if Array === n +# outputs, inputs, block = n +# inputs_time = inputs.map {|f| File.mtime f}.max +# begin +# outputs_time = outputs.map {|f| File.mtime f}.min +# rescue Errno::ENOENT +# outputs_time = nil +# end +# if outputs_time == nil || +# inputs_time != nil && outputs_time <= inputs_time +# sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i +# block.call +# end +# end +# } +# end +# +# def tsort_each_child(node, &block) +# @dep[node].each(&block) +# end +# include Bundler::TSort +# end +# +# def command(arg) +# print arg, "\n" +# system arg +# end +# +# m = Make.new +# m.rule(%w[t1]) { command 'date > t1' } +# m.rule(%w[t2]) { command 'date > t2' } +# m.rule(%w[t3]) { command 'date > t3' } +# m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' } +# m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' } +# m.build('t5') +# +# == Bugs +# +# * 'tsort.rb' is wrong name because this library uses +# Tarjan's algorithm for strongly connected components. +# Although 'strongly_connected_components.rb' is correct but too long. +# +# == References +# +# R. E. Tarjan, "Depth First Search and Linear Graph Algorithms", +# SIAM Journal on Computing, Vol. 1, No. 2, pp. 146-160, June 1972. +# + +module Bundler::TSort + class Cyclic < StandardError + end + + # Returns a topologically sorted array of nodes. + # The array is sorted from children to parents, i.e. + # the first element has no child and the last node has no parent. + # + # If there is a cycle, Bundler::TSort::Cyclic is raised. + # + # class G + # include Bundler::TSort + # def initialize(g) + # @g = g + # end + # def tsort_each_child(n, &b) @g[n].each(&b) end + # def tsort_each_node(&b) @g.each_key(&b) end + # end + # + # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}) + # p graph.tsort #=> [4, 2, 3, 1] + # + # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}) + # p graph.tsort # raises Bundler::TSort::Cyclic + # + def tsort + each_node = method(:tsort_each_node) + each_child = method(:tsort_each_child) + Bundler::TSort.tsort(each_node, each_child) + end + + # Returns a topologically sorted array of nodes. + # The array is sorted from children to parents, i.e. + # the first element has no child and the last node has no parent. + # + # The graph is represented by _each_node_ and _each_child_. + # _each_node_ should have +call+ method which yields for each node in the graph. + # _each_child_ should have +call+ method which takes a node argument and yields for each child node. + # + # If there is a cycle, Bundler::TSort::Cyclic is raised. + # + # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]} + # each_node = lambda {|&b| g.each_key(&b) } + # each_child = lambda {|n, &b| g[n].each(&b) } + # p Bundler::TSort.tsort(each_node, each_child) #=> [4, 2, 3, 1] + # + # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]} + # each_node = lambda {|&b| g.each_key(&b) } + # each_child = lambda {|n, &b| g[n].each(&b) } + # p Bundler::TSort.tsort(each_node, each_child) # raises Bundler::TSort::Cyclic + # + def self.tsort(each_node, each_child) + tsort_each(each_node, each_child).to_a + end + + # The iterator version of the #tsort method. + # obj.tsort_each is similar to obj.tsort.each, but + # modification of _obj_ during the iteration may lead to unexpected results. + # + # #tsort_each returns +nil+. + # If there is a cycle, Bundler::TSort::Cyclic is raised. + # + # class G + # include Bundler::TSort + # def initialize(g) + # @g = g + # end + # def tsort_each_child(n, &b) @g[n].each(&b) end + # def tsort_each_node(&b) @g.each_key(&b) end + # end + # + # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}) + # graph.tsort_each {|n| p n } + # #=> 4 + # # 2 + # # 3 + # # 1 + # + def tsort_each(&block) # :yields: node + each_node = method(:tsort_each_node) + each_child = method(:tsort_each_child) + Bundler::TSort.tsort_each(each_node, each_child, &block) + end + + # The iterator version of the Bundler::TSort.tsort method. + # + # The graph is represented by _each_node_ and _each_child_. + # _each_node_ should have +call+ method which yields for each node in the graph. + # _each_child_ should have +call+ method which takes a node argument and yields for each child node. + # + # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]} + # each_node = lambda {|&b| g.each_key(&b) } + # each_child = lambda {|n, &b| g[n].each(&b) } + # Bundler::TSort.tsort_each(each_node, each_child) {|n| p n } + # #=> 4 + # # 2 + # # 3 + # # 1 + # + def self.tsort_each(each_node, each_child) # :yields: node + return to_enum(__method__, each_node, each_child) unless block_given? + + each_strongly_connected_component(each_node, each_child) {|component| + if component.size == 1 + yield component.first + else + raise Cyclic.new("topological sort failed: #{component.inspect}") + end + } + end + + # Returns strongly connected components as an array of arrays of nodes. + # The array is sorted from children to parents. + # Each elements of the array represents a strongly connected component. + # + # class G + # include Bundler::TSort + # def initialize(g) + # @g = g + # end + # def tsort_each_child(n, &b) @g[n].each(&b) end + # def tsort_each_node(&b) @g.each_key(&b) end + # end + # + # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}) + # p graph.strongly_connected_components #=> [[4], [2], [3], [1]] + # + # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}) + # p graph.strongly_connected_components #=> [[4], [2, 3], [1]] + # + def strongly_connected_components + each_node = method(:tsort_each_node) + each_child = method(:tsort_each_child) + Bundler::TSort.strongly_connected_components(each_node, each_child) + end + + # Returns strongly connected components as an array of arrays of nodes. + # The array is sorted from children to parents. + # Each elements of the array represents a strongly connected component. + # + # The graph is represented by _each_node_ and _each_child_. + # _each_node_ should have +call+ method which yields for each node in the graph. + # _each_child_ should have +call+ method which takes a node argument and yields for each child node. + # + # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]} + # each_node = lambda {|&b| g.each_key(&b) } + # each_child = lambda {|n, &b| g[n].each(&b) } + # p Bundler::TSort.strongly_connected_components(each_node, each_child) + # #=> [[4], [2], [3], [1]] + # + # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]} + # each_node = lambda {|&b| g.each_key(&b) } + # each_child = lambda {|n, &b| g[n].each(&b) } + # p Bundler::TSort.strongly_connected_components(each_node, each_child) + # #=> [[4], [2, 3], [1]] + # + def self.strongly_connected_components(each_node, each_child) + each_strongly_connected_component(each_node, each_child).to_a + end + + # The iterator version of the #strongly_connected_components method. + # obj.each_strongly_connected_component is similar to + # obj.strongly_connected_components.each, but + # modification of _obj_ during the iteration may lead to unexpected results. + # + # #each_strongly_connected_component returns +nil+. + # + # class G + # include Bundler::TSort + # def initialize(g) + # @g = g + # end + # def tsort_each_child(n, &b) @g[n].each(&b) end + # def tsort_each_node(&b) @g.each_key(&b) end + # end + # + # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}) + # graph.each_strongly_connected_component {|scc| p scc } + # #=> [4] + # # [2] + # # [3] + # # [1] + # + # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}) + # graph.each_strongly_connected_component {|scc| p scc } + # #=> [4] + # # [2, 3] + # # [1] + # + def each_strongly_connected_component(&block) # :yields: nodes + each_node = method(:tsort_each_node) + each_child = method(:tsort_each_child) + Bundler::TSort.each_strongly_connected_component(each_node, each_child, &block) + end + + # The iterator version of the Bundler::TSort.strongly_connected_components method. + # + # The graph is represented by _each_node_ and _each_child_. + # _each_node_ should have +call+ method which yields for each node in the graph. + # _each_child_ should have +call+ method which takes a node argument and yields for each child node. + # + # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]} + # each_node = lambda {|&b| g.each_key(&b) } + # each_child = lambda {|n, &b| g[n].each(&b) } + # Bundler::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc } + # #=> [4] + # # [2] + # # [3] + # # [1] + # + # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]} + # each_node = lambda {|&b| g.each_key(&b) } + # each_child = lambda {|n, &b| g[n].each(&b) } + # Bundler::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc } + # #=> [4] + # # [2, 3] + # # [1] + # + def self.each_strongly_connected_component(each_node, each_child) # :yields: nodes + return to_enum(__method__, each_node, each_child) unless block_given? + + id_map = {} + stack = [] + each_node.call {|node| + unless id_map.include? node + each_strongly_connected_component_from(node, each_child, id_map, stack) {|c| + yield c + } + end + } + nil + end + + # Iterates over strongly connected component in the subgraph reachable from + # _node_. + # + # Return value is unspecified. + # + # #each_strongly_connected_component_from doesn't call #tsort_each_node. + # + # class G + # include Bundler::TSort + # def initialize(g) + # @g = g + # end + # def tsort_each_child(n, &b) @g[n].each(&b) end + # def tsort_each_node(&b) @g.each_key(&b) end + # end + # + # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}) + # graph.each_strongly_connected_component_from(2) {|scc| p scc } + # #=> [4] + # # [2] + # + # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}) + # graph.each_strongly_connected_component_from(2) {|scc| p scc } + # #=> [4] + # # [2, 3] + # + def each_strongly_connected_component_from(node, id_map={}, stack=[], &block) # :yields: nodes + Bundler::TSort.each_strongly_connected_component_from(node, method(:tsort_each_child), id_map, stack, &block) + end + + # Iterates over strongly connected components in a graph. + # The graph is represented by _node_ and _each_child_. + # + # _node_ is the first node. + # _each_child_ should have +call+ method which takes a node argument + # and yields for each child node. + # + # Return value is unspecified. + # + # #Bundler::TSort.each_strongly_connected_component_from is a class method and + # it doesn't need a class to represent a graph which includes Bundler::TSort. + # + # graph = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]} + # each_child = lambda {|n, &b| graph[n].each(&b) } + # Bundler::TSort.each_strongly_connected_component_from(1, each_child) {|scc| + # p scc + # } + # #=> [4] + # # [2, 3] + # # [1] + # + def self.each_strongly_connected_component_from(node, each_child, id_map={}, stack=[]) # :yields: nodes + return to_enum(__method__, node, each_child, id_map, stack) unless block_given? + + minimum_id = node_id = id_map[node] = id_map.size + stack_length = stack.length + stack << node + + each_child.call(node) {|child| + if id_map.include? child + child_id = id_map[child] + minimum_id = child_id if child_id && child_id < minimum_id + else + sub_minimum_id = + each_strongly_connected_component_from(child, each_child, id_map, stack) {|c| + yield c + } + minimum_id = sub_minimum_id if sub_minimum_id < minimum_id + end + } + + if node_id == minimum_id + component = stack.slice!(stack_length .. -1) + component.each {|n| id_map[n] = nil} + yield component + end + + minimum_id + end + + # Should be implemented by a extended class. + # + # #tsort_each_node is used to iterate for all nodes over a graph. + # + def tsort_each_node # :yields: node + raise NotImplementedError.new + end + + # Should be implemented by a extended class. + # + # #tsort_each_child is used to iterate for child nodes of _node_. + # + def tsort_each_child(node) # :yields: child + raise NotImplementedError.new + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri.rb new file mode 100644 index 0000000..0e574dd --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: false +# Bundler::URI is a module providing classes to handle Uniform Resource Identifiers +# (RFC2396[http://tools.ietf.org/html/rfc2396]). +# +# == Features +# +# * Uniform way of handling URIs. +# * Flexibility to introduce custom Bundler::URI schemes. +# * Flexibility to have an alternate Bundler::URI::Parser (or just different patterns +# and regexp's). +# +# == Basic example +# +# require 'bundler/vendor/uri/lib/uri' +# +# uri = Bundler::URI("http://foo.com/posts?id=30&limit=5#time=1305298413") +# #=> # +# +# uri.scheme #=> "http" +# uri.host #=> "foo.com" +# uri.path #=> "/posts" +# uri.query #=> "id=30&limit=5" +# uri.fragment #=> "time=1305298413" +# +# uri.to_s #=> "http://foo.com/posts?id=30&limit=5#time=1305298413" +# +# == Adding custom URIs +# +# module Bundler::URI +# class RSYNC < Generic +# DEFAULT_PORT = 873 +# end +# @@schemes['RSYNC'] = RSYNC +# end +# #=> Bundler::URI::RSYNC +# +# Bundler::URI.scheme_list +# #=> {"FILE"=>Bundler::URI::File, "FTP"=>Bundler::URI::FTP, "HTTP"=>Bundler::URI::HTTP, +# # "HTTPS"=>Bundler::URI::HTTPS, "LDAP"=>Bundler::URI::LDAP, "LDAPS"=>Bundler::URI::LDAPS, +# # "MAILTO"=>Bundler::URI::MailTo, "RSYNC"=>Bundler::URI::RSYNC} +# +# uri = Bundler::URI("rsync://rsync.foo.com") +# #=> # +# +# == RFC References +# +# A good place to view an RFC spec is http://www.ietf.org/rfc.html. +# +# Here is a list of all related RFC's: +# - RFC822[http://tools.ietf.org/html/rfc822] +# - RFC1738[http://tools.ietf.org/html/rfc1738] +# - RFC2255[http://tools.ietf.org/html/rfc2255] +# - RFC2368[http://tools.ietf.org/html/rfc2368] +# - RFC2373[http://tools.ietf.org/html/rfc2373] +# - RFC2396[http://tools.ietf.org/html/rfc2396] +# - RFC2732[http://tools.ietf.org/html/rfc2732] +# - RFC3986[http://tools.ietf.org/html/rfc3986] +# +# == Class tree +# +# - Bundler::URI::Generic (in uri/generic.rb) +# - Bundler::URI::File - (in uri/file.rb) +# - Bundler::URI::FTP - (in uri/ftp.rb) +# - Bundler::URI::HTTP - (in uri/http.rb) +# - Bundler::URI::HTTPS - (in uri/https.rb) +# - Bundler::URI::LDAP - (in uri/ldap.rb) +# - Bundler::URI::LDAPS - (in uri/ldaps.rb) +# - Bundler::URI::MailTo - (in uri/mailto.rb) +# - Bundler::URI::Parser - (in uri/common.rb) +# - Bundler::URI::REGEXP - (in uri/common.rb) +# - Bundler::URI::REGEXP::PATTERN - (in uri/common.rb) +# - Bundler::URI::Util - (in uri/common.rb) +# - Bundler::URI::Escape - (in uri/common.rb) +# - Bundler::URI::Error - (in uri/common.rb) +# - Bundler::URI::InvalidURIError - (in uri/common.rb) +# - Bundler::URI::InvalidComponentError - (in uri/common.rb) +# - Bundler::URI::BadURIError - (in uri/common.rb) +# +# == Copyright Info +# +# Author:: Akira Yamada +# Documentation:: +# Akira Yamada +# Dmitry V. Sabanin +# Vincent Batts +# License:: +# Copyright (c) 2001 akira yamada +# You can redistribute it and/or modify it under the same term as Ruby. +# + +module Bundler::URI +end + +require_relative 'uri/version' +require_relative 'uri/common' +require_relative 'uri/generic' +require_relative 'uri/file' +require_relative 'uri/ftp' +require_relative 'uri/http' +require_relative 'uri/https' +require_relative 'uri/ldap' +require_relative 'uri/ldaps' +require_relative 'uri/mailto' diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/common.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/common.rb new file mode 100644 index 0000000..6539e18 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/common.rb @@ -0,0 +1,681 @@ +# frozen_string_literal: true +#-- +# = uri/common.rb +# +# Author:: Akira Yamada +# License:: +# You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +require_relative "rfc2396_parser" +require_relative "rfc3986_parser" + +module Bundler::URI + REGEXP = RFC2396_REGEXP + Parser = RFC2396_Parser + RFC3986_PARSER = RFC3986_Parser.new + + # Bundler::URI::Parser.new + DEFAULT_PARSER = Parser.new + DEFAULT_PARSER.pattern.each_pair do |sym, str| + unless REGEXP::PATTERN.const_defined?(sym) + REGEXP::PATTERN.const_set(sym, str) + end + end + DEFAULT_PARSER.regexp.each_pair do |sym, str| + const_set(sym, str) + end + + module Util # :nodoc: + def make_components_hash(klass, array_hash) + tmp = {} + if array_hash.kind_of?(Array) && + array_hash.size == klass.component.size - 1 + klass.component[1..-1].each_index do |i| + begin + tmp[klass.component[i + 1]] = array_hash[i].clone + rescue TypeError + tmp[klass.component[i + 1]] = array_hash[i] + end + end + + elsif array_hash.kind_of?(Hash) + array_hash.each do |key, value| + begin + tmp[key] = value.clone + rescue TypeError + tmp[key] = value + end + end + else + raise ArgumentError, + "expected Array of or Hash of components of #{klass} (#{klass.component[1..-1].join(', ')})" + end + tmp[:scheme] = klass.to_s.sub(/\A.*::/, '').downcase + + return tmp + end + module_function :make_components_hash + end + + include REGEXP + + @@schemes = {} + # Returns a Hash of the defined schemes. + def self.scheme_list + @@schemes + end + + # + # Construct a Bundler::URI instance, using the scheme to detect the appropriate class + # from +Bundler::URI.scheme_list+. + # + def self.for(scheme, *arguments, default: Generic) + if scheme + uri_class = @@schemes[scheme.upcase] || default + else + uri_class = default + end + + return uri_class.new(scheme, *arguments) + end + + # + # Base class for all Bundler::URI exceptions. + # + class Error < StandardError; end + # + # Not a Bundler::URI. + # + class InvalidURIError < Error; end + # + # Not a Bundler::URI component. + # + class InvalidComponentError < Error; end + # + # Bundler::URI is valid, bad usage is not. + # + class BadURIError < Error; end + + # + # == Synopsis + # + # Bundler::URI::split(uri) + # + # == Args + # + # +uri+:: + # String with Bundler::URI. + # + # == Description + # + # Splits the string on following parts and returns array with result: + # + # * Scheme + # * Userinfo + # * Host + # * Port + # * Registry + # * Path + # * Opaque + # * Query + # * Fragment + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # Bundler::URI.split("http://www.ruby-lang.org/") + # # => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil] + # + def self.split(uri) + RFC3986_PARSER.split(uri) + end + + # + # == Synopsis + # + # Bundler::URI::parse(uri_str) + # + # == Args + # + # +uri_str+:: + # String with Bundler::URI. + # + # == Description + # + # Creates one of the Bundler::URI's subclasses instance from the string. + # + # == Raises + # + # Bundler::URI::InvalidURIError:: + # Raised if Bundler::URI given is not a correct one. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://www.ruby-lang.org/") + # # => # + # uri.scheme + # # => "http" + # uri.host + # # => "www.ruby-lang.org" + # + # It's recommended to first ::escape the provided +uri_str+ if there are any + # invalid Bundler::URI characters. + # + def self.parse(uri) + RFC3986_PARSER.parse(uri) + end + + # + # == Synopsis + # + # Bundler::URI::join(str[, str, ...]) + # + # == Args + # + # +str+:: + # String(s) to work with, will be converted to RFC3986 URIs before merging. + # + # == Description + # + # Joins URIs. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # Bundler::URI.join("http://example.com/","main.rbx") + # # => # + # + # Bundler::URI.join('http://example.com', 'foo') + # # => # + # + # Bundler::URI.join('http://example.com', '/foo', '/bar') + # # => # + # + # Bundler::URI.join('http://example.com', '/foo', 'bar') + # # => # + # + # Bundler::URI.join('http://example.com', '/foo/', 'bar') + # # => # + # + def self.join(*str) + RFC3986_PARSER.join(*str) + end + + # + # == Synopsis + # + # Bundler::URI::extract(str[, schemes][,&blk]) + # + # == Args + # + # +str+:: + # String to extract URIs from. + # +schemes+:: + # Limit Bundler::URI matching to specific schemes. + # + # == Description + # + # Extracts URIs from a string. If block given, iterates through all matched URIs. + # Returns nil if block given or array with matches. + # + # == Usage + # + # require "bundler/vendor/uri/lib/uri" + # + # Bundler::URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.") + # # => ["http://foo.example.com/bla", "mailto:test@example.com"] + # + def self.extract(str, schemes = nil, &block) + warn "Bundler::URI.extract is obsolete", uplevel: 1 if $VERBOSE + DEFAULT_PARSER.extract(str, schemes, &block) + end + + # + # == Synopsis + # + # Bundler::URI::regexp([match_schemes]) + # + # == Args + # + # +match_schemes+:: + # Array of schemes. If given, resulting regexp matches to URIs + # whose scheme is one of the match_schemes. + # + # == Description + # + # Returns a Regexp object which matches to Bundler::URI-like strings. + # The Regexp object returned by this method includes arbitrary + # number of capture group (parentheses). Never rely on its number. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # # extract first Bundler::URI from html_string + # html_string.slice(Bundler::URI.regexp) + # + # # remove ftp URIs + # html_string.sub(Bundler::URI.regexp(['ftp']), '') + # + # # You should not rely on the number of parentheses + # html_string.scan(Bundler::URI.regexp) do |*matches| + # p $& + # end + # + def self.regexp(schemes = nil) + warn "Bundler::URI.regexp is obsolete", uplevel: 1 if $VERBOSE + DEFAULT_PARSER.make_regexp(schemes) + end + + TBLENCWWWCOMP_ = {} # :nodoc: + 256.times do |i| + TBLENCWWWCOMP_[-i.chr] = -('%%%02X' % i) + end + TBLENCWWWCOMP_[' '] = '+' + TBLENCWWWCOMP_.freeze + TBLDECWWWCOMP_ = {} # :nodoc: + 256.times do |i| + h, l = i>>4, i&15 + TBLDECWWWCOMP_[-('%%%X%X' % [h, l])] = -i.chr + TBLDECWWWCOMP_[-('%%%x%X' % [h, l])] = -i.chr + TBLDECWWWCOMP_[-('%%%X%x' % [h, l])] = -i.chr + TBLDECWWWCOMP_[-('%%%x%x' % [h, l])] = -i.chr + end + TBLDECWWWCOMP_['+'] = ' ' + TBLDECWWWCOMP_.freeze + + # Encodes given +str+ to URL-encoded form data. + # + # This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP + # (ASCII space) to + and converts others to %XX. + # + # If +enc+ is given, convert +str+ to the encoding before percent encoding. + # + # This is an implementation of + # https://www.w3.org/TR/2013/CR-html5-20130806/forms.html#url-encoded-form-data. + # + # See Bundler::URI.decode_www_form_component, Bundler::URI.encode_www_form. + def self.encode_www_form_component(str, enc=nil) + str = str.to_s.dup + if str.encoding != Encoding::ASCII_8BIT + if enc && enc != Encoding::ASCII_8BIT + str.encode!(Encoding::UTF_8, invalid: :replace, undef: :replace) + str.encode!(enc, fallback: ->(x){"&##{x.ord};"}) + end + str.force_encoding(Encoding::ASCII_8BIT) + end + str.gsub!(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_) + str.force_encoding(Encoding::US_ASCII) + end + + # Decodes given +str+ of URL-encoded form data. + # + # This decodes + to SP. + # + # See Bundler::URI.encode_www_form_component, Bundler::URI.decode_www_form. + def self.decode_www_form_component(str, enc=Encoding::UTF_8) + raise ArgumentError, "invalid %-encoding (#{str})" if /%(?!\h\h)/ =~ str + str.b.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(enc) + end + + # Generates URL-encoded form data from given +enum+. + # + # This generates application/x-www-form-urlencoded data defined in HTML5 + # from given an Enumerable object. + # + # This internally uses Bundler::URI.encode_www_form_component(str). + # + # This method doesn't convert the encoding of given items, so convert them + # before calling this method if you want to send data as other than original + # encoding or mixed encoding data. (Strings which are encoded in an HTML5 + # ASCII incompatible encoding are converted to UTF-8.) + # + # This method doesn't handle files. When you send a file, use + # multipart/form-data. + # + # This refers https://url.spec.whatwg.org/#concept-urlencoded-serializer + # + # Bundler::URI.encode_www_form([["q", "ruby"], ["lang", "en"]]) + # #=> "q=ruby&lang=en" + # Bundler::URI.encode_www_form("q" => "ruby", "lang" => "en") + # #=> "q=ruby&lang=en" + # Bundler::URI.encode_www_form("q" => ["ruby", "perl"], "lang" => "en") + # #=> "q=ruby&q=perl&lang=en" + # Bundler::URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]]) + # #=> "q=ruby&q=perl&lang=en" + # + # See Bundler::URI.encode_www_form_component, Bundler::URI.decode_www_form. + def self.encode_www_form(enum, enc=nil) + enum.map do |k,v| + if v.nil? + encode_www_form_component(k, enc) + elsif v.respond_to?(:to_ary) + v.to_ary.map do |w| + str = encode_www_form_component(k, enc) + unless w.nil? + str << '=' + str << encode_www_form_component(w, enc) + end + end.join('&') + else + str = encode_www_form_component(k, enc) + str << '=' + str << encode_www_form_component(v, enc) + end + end.join('&') + end + + # Decodes URL-encoded form data from given +str+. + # + # This decodes application/x-www-form-urlencoded data + # and returns an array of key-value arrays. + # + # This refers http://url.spec.whatwg.org/#concept-urlencoded-parser, + # so this supports only &-separator, and doesn't support ;-separator. + # + # ary = Bundler::URI.decode_www_form("a=1&a=2&b=3") + # ary #=> [['a', '1'], ['a', '2'], ['b', '3']] + # ary.assoc('a').last #=> '1' + # ary.assoc('b').last #=> '3' + # ary.rassoc('a').last #=> '2' + # Hash[ary] #=> {"a"=>"2", "b"=>"3"} + # + # See Bundler::URI.decode_www_form_component, Bundler::URI.encode_www_form. + def self.decode_www_form(str, enc=Encoding::UTF_8, separator: '&', use__charset_: false, isindex: false) + raise ArgumentError, "the input of #{self.name}.#{__method__} must be ASCII only string" unless str.ascii_only? + ary = [] + return ary if str.empty? + enc = Encoding.find(enc) + str.b.each_line(separator) do |string| + string.chomp!(separator) + key, sep, val = string.partition('=') + if isindex + if sep.empty? + val = key + key = +'' + end + isindex = false + end + + if use__charset_ and key == '_charset_' and e = get_encoding(val) + enc = e + use__charset_ = false + end + + key.gsub!(/\+|%\h\h/, TBLDECWWWCOMP_) + if val + val.gsub!(/\+|%\h\h/, TBLDECWWWCOMP_) + else + val = +'' + end + + ary << [key, val] + end + ary.each do |k, v| + k.force_encoding(enc) + k.scrub! + v.force_encoding(enc) + v.scrub! + end + ary + end + + private +=begin command for WEB_ENCODINGS_ + curl https://encoding.spec.whatwg.org/encodings.json| + ruby -rjson -e 'H={} + h={ + "shift_jis"=>"Windows-31J", + "euc-jp"=>"cp51932", + "iso-2022-jp"=>"cp50221", + "x-mac-cyrillic"=>"macCyrillic", + } + JSON($<.read).map{|x|x["encodings"]}.flatten.each{|x| + Encoding.find(n=h.fetch(n=x["name"].downcase,n))rescue next + x["labels"].each{|y|H[y]=n} + } + puts "{" + H.each{|k,v|puts %[ #{k.dump}=>#{v.dump},]} + puts "}" +' +=end + WEB_ENCODINGS_ = { + "unicode-1-1-utf-8"=>"utf-8", + "utf-8"=>"utf-8", + "utf8"=>"utf-8", + "866"=>"ibm866", + "cp866"=>"ibm866", + "csibm866"=>"ibm866", + "ibm866"=>"ibm866", + "csisolatin2"=>"iso-8859-2", + "iso-8859-2"=>"iso-8859-2", + "iso-ir-101"=>"iso-8859-2", + "iso8859-2"=>"iso-8859-2", + "iso88592"=>"iso-8859-2", + "iso_8859-2"=>"iso-8859-2", + "iso_8859-2:1987"=>"iso-8859-2", + "l2"=>"iso-8859-2", + "latin2"=>"iso-8859-2", + "csisolatin3"=>"iso-8859-3", + "iso-8859-3"=>"iso-8859-3", + "iso-ir-109"=>"iso-8859-3", + "iso8859-3"=>"iso-8859-3", + "iso88593"=>"iso-8859-3", + "iso_8859-3"=>"iso-8859-3", + "iso_8859-3:1988"=>"iso-8859-3", + "l3"=>"iso-8859-3", + "latin3"=>"iso-8859-3", + "csisolatin4"=>"iso-8859-4", + "iso-8859-4"=>"iso-8859-4", + "iso-ir-110"=>"iso-8859-4", + "iso8859-4"=>"iso-8859-4", + "iso88594"=>"iso-8859-4", + "iso_8859-4"=>"iso-8859-4", + "iso_8859-4:1988"=>"iso-8859-4", + "l4"=>"iso-8859-4", + "latin4"=>"iso-8859-4", + "csisolatincyrillic"=>"iso-8859-5", + "cyrillic"=>"iso-8859-5", + "iso-8859-5"=>"iso-8859-5", + "iso-ir-144"=>"iso-8859-5", + "iso8859-5"=>"iso-8859-5", + "iso88595"=>"iso-8859-5", + "iso_8859-5"=>"iso-8859-5", + "iso_8859-5:1988"=>"iso-8859-5", + "arabic"=>"iso-8859-6", + "asmo-708"=>"iso-8859-6", + "csiso88596e"=>"iso-8859-6", + "csiso88596i"=>"iso-8859-6", + "csisolatinarabic"=>"iso-8859-6", + "ecma-114"=>"iso-8859-6", + "iso-8859-6"=>"iso-8859-6", + "iso-8859-6-e"=>"iso-8859-6", + "iso-8859-6-i"=>"iso-8859-6", + "iso-ir-127"=>"iso-8859-6", + "iso8859-6"=>"iso-8859-6", + "iso88596"=>"iso-8859-6", + "iso_8859-6"=>"iso-8859-6", + "iso_8859-6:1987"=>"iso-8859-6", + "csisolatingreek"=>"iso-8859-7", + "ecma-118"=>"iso-8859-7", + "elot_928"=>"iso-8859-7", + "greek"=>"iso-8859-7", + "greek8"=>"iso-8859-7", + "iso-8859-7"=>"iso-8859-7", + "iso-ir-126"=>"iso-8859-7", + "iso8859-7"=>"iso-8859-7", + "iso88597"=>"iso-8859-7", + "iso_8859-7"=>"iso-8859-7", + "iso_8859-7:1987"=>"iso-8859-7", + "sun_eu_greek"=>"iso-8859-7", + "csiso88598e"=>"iso-8859-8", + "csisolatinhebrew"=>"iso-8859-8", + "hebrew"=>"iso-8859-8", + "iso-8859-8"=>"iso-8859-8", + "iso-8859-8-e"=>"iso-8859-8", + "iso-ir-138"=>"iso-8859-8", + "iso8859-8"=>"iso-8859-8", + "iso88598"=>"iso-8859-8", + "iso_8859-8"=>"iso-8859-8", + "iso_8859-8:1988"=>"iso-8859-8", + "visual"=>"iso-8859-8", + "csisolatin6"=>"iso-8859-10", + "iso-8859-10"=>"iso-8859-10", + "iso-ir-157"=>"iso-8859-10", + "iso8859-10"=>"iso-8859-10", + "iso885910"=>"iso-8859-10", + "l6"=>"iso-8859-10", + "latin6"=>"iso-8859-10", + "iso-8859-13"=>"iso-8859-13", + "iso8859-13"=>"iso-8859-13", + "iso885913"=>"iso-8859-13", + "iso-8859-14"=>"iso-8859-14", + "iso8859-14"=>"iso-8859-14", + "iso885914"=>"iso-8859-14", + "csisolatin9"=>"iso-8859-15", + "iso-8859-15"=>"iso-8859-15", + "iso8859-15"=>"iso-8859-15", + "iso885915"=>"iso-8859-15", + "iso_8859-15"=>"iso-8859-15", + "l9"=>"iso-8859-15", + "iso-8859-16"=>"iso-8859-16", + "cskoi8r"=>"koi8-r", + "koi"=>"koi8-r", + "koi8"=>"koi8-r", + "koi8-r"=>"koi8-r", + "koi8_r"=>"koi8-r", + "koi8-ru"=>"koi8-u", + "koi8-u"=>"koi8-u", + "dos-874"=>"windows-874", + "iso-8859-11"=>"windows-874", + "iso8859-11"=>"windows-874", + "iso885911"=>"windows-874", + "tis-620"=>"windows-874", + "windows-874"=>"windows-874", + "cp1250"=>"windows-1250", + "windows-1250"=>"windows-1250", + "x-cp1250"=>"windows-1250", + "cp1251"=>"windows-1251", + "windows-1251"=>"windows-1251", + "x-cp1251"=>"windows-1251", + "ansi_x3.4-1968"=>"windows-1252", + "ascii"=>"windows-1252", + "cp1252"=>"windows-1252", + "cp819"=>"windows-1252", + "csisolatin1"=>"windows-1252", + "ibm819"=>"windows-1252", + "iso-8859-1"=>"windows-1252", + "iso-ir-100"=>"windows-1252", + "iso8859-1"=>"windows-1252", + "iso88591"=>"windows-1252", + "iso_8859-1"=>"windows-1252", + "iso_8859-1:1987"=>"windows-1252", + "l1"=>"windows-1252", + "latin1"=>"windows-1252", + "us-ascii"=>"windows-1252", + "windows-1252"=>"windows-1252", + "x-cp1252"=>"windows-1252", + "cp1253"=>"windows-1253", + "windows-1253"=>"windows-1253", + "x-cp1253"=>"windows-1253", + "cp1254"=>"windows-1254", + "csisolatin5"=>"windows-1254", + "iso-8859-9"=>"windows-1254", + "iso-ir-148"=>"windows-1254", + "iso8859-9"=>"windows-1254", + "iso88599"=>"windows-1254", + "iso_8859-9"=>"windows-1254", + "iso_8859-9:1989"=>"windows-1254", + "l5"=>"windows-1254", + "latin5"=>"windows-1254", + "windows-1254"=>"windows-1254", + "x-cp1254"=>"windows-1254", + "cp1255"=>"windows-1255", + "windows-1255"=>"windows-1255", + "x-cp1255"=>"windows-1255", + "cp1256"=>"windows-1256", + "windows-1256"=>"windows-1256", + "x-cp1256"=>"windows-1256", + "cp1257"=>"windows-1257", + "windows-1257"=>"windows-1257", + "x-cp1257"=>"windows-1257", + "cp1258"=>"windows-1258", + "windows-1258"=>"windows-1258", + "x-cp1258"=>"windows-1258", + "x-mac-cyrillic"=>"macCyrillic", + "x-mac-ukrainian"=>"macCyrillic", + "chinese"=>"gbk", + "csgb2312"=>"gbk", + "csiso58gb231280"=>"gbk", + "gb2312"=>"gbk", + "gb_2312"=>"gbk", + "gb_2312-80"=>"gbk", + "gbk"=>"gbk", + "iso-ir-58"=>"gbk", + "x-gbk"=>"gbk", + "gb18030"=>"gb18030", + "big5"=>"big5", + "big5-hkscs"=>"big5", + "cn-big5"=>"big5", + "csbig5"=>"big5", + "x-x-big5"=>"big5", + "cseucpkdfmtjapanese"=>"cp51932", + "euc-jp"=>"cp51932", + "x-euc-jp"=>"cp51932", + "csiso2022jp"=>"cp50221", + "iso-2022-jp"=>"cp50221", + "csshiftjis"=>"Windows-31J", + "ms932"=>"Windows-31J", + "ms_kanji"=>"Windows-31J", + "shift-jis"=>"Windows-31J", + "shift_jis"=>"Windows-31J", + "sjis"=>"Windows-31J", + "windows-31j"=>"Windows-31J", + "x-sjis"=>"Windows-31J", + "cseuckr"=>"euc-kr", + "csksc56011987"=>"euc-kr", + "euc-kr"=>"euc-kr", + "iso-ir-149"=>"euc-kr", + "korean"=>"euc-kr", + "ks_c_5601-1987"=>"euc-kr", + "ks_c_5601-1989"=>"euc-kr", + "ksc5601"=>"euc-kr", + "ksc_5601"=>"euc-kr", + "windows-949"=>"euc-kr", + "utf-16be"=>"utf-16be", + "utf-16"=>"utf-16le", + "utf-16le"=>"utf-16le", + } # :nodoc: + + # :nodoc: + # return encoding or nil + # http://encoding.spec.whatwg.org/#concept-encoding-get + def self.get_encoding(label) + Encoding.find(WEB_ENCODINGS_[label.to_str.strip.downcase]) rescue nil + end +end # module Bundler::URI + +module Bundler + + # + # Returns +uri+ converted to an Bundler::URI object. + # + def URI(uri) + if uri.is_a?(Bundler::URI::Generic) + uri + elsif uri = String.try_convert(uri) + Bundler::URI.parse(uri) + else + raise ArgumentError, + "bad argument (expected Bundler::URI object or Bundler::URI string)" + end + end + module_function :URI +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/file.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/file.rb new file mode 100644 index 0000000..df42f8b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/file.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +require_relative 'generic' + +module Bundler::URI + + # + # The "file" Bundler::URI is defined by RFC8089. + # + class File < Generic + # A Default port of nil for Bundler::URI::File. + DEFAULT_PORT = nil + + # + # An Array of the available components for Bundler::URI::File. + # + COMPONENT = [ + :scheme, + :host, + :path + ].freeze + + # + # == Description + # + # Creates a new Bundler::URI::File object from components, with syntax checking. + # + # The components accepted are +host+ and +path+. + # + # The components should be provided either as an Array, or as a Hash + # with keys formed by preceding the component names with a colon. + # + # If an Array is used, the components must be passed in the + # order [host, path]. + # + # Examples: + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri1 = Bundler::URI::File.build(['host.example.com', '/path/file.zip']) + # uri1.to_s # => "file://host.example.com/path/file.zip" + # + # uri2 = Bundler::URI::File.build({:host => 'host.example.com', + # :path => '/ruby/src'}) + # uri2.to_s # => "file://host.example.com/ruby/src" + # + def self.build(args) + tmp = Util::make_components_hash(self, args) + super(tmp) + end + + # Protected setter for the host component +v+. + # + # See also Bundler::URI::Generic.host=. + # + def set_host(v) + v = "" if v.nil? || v == "localhost" + @host = v + end + + # do nothing + def set_port(v) + end + + # raise InvalidURIError + def check_userinfo(user) + raise Bundler::URI::InvalidURIError, "can not set userinfo for file Bundler::URI" + end + + # raise InvalidURIError + def check_user(user) + raise Bundler::URI::InvalidURIError, "can not set user for file Bundler::URI" + end + + # raise InvalidURIError + def check_password(user) + raise Bundler::URI::InvalidURIError, "can not set password for file Bundler::URI" + end + + # do nothing + def set_userinfo(v) + end + + # do nothing + def set_user(v) + end + + # do nothing + def set_password(v) + end + end + + @@schemes['FILE'] = File +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/ftp.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/ftp.rb new file mode 100644 index 0000000..2252e40 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/ftp.rb @@ -0,0 +1,266 @@ +# frozen_string_literal: false +# = uri/ftp.rb +# +# Author:: Akira Yamada +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +require_relative 'generic' + +module Bundler::URI + + # + # FTP Bundler::URI syntax is defined by RFC1738 section 3.2. + # + # This class will be redesigned because of difference of implementations; + # the structure of its path. draft-hoffman-ftp-uri-04 is a draft but it + # is a good summary about the de facto spec. + # http://tools.ietf.org/html/draft-hoffman-ftp-uri-04 + # + class FTP < Generic + # A Default port of 21 for Bundler::URI::FTP. + DEFAULT_PORT = 21 + + # + # An Array of the available components for Bundler::URI::FTP. + # + COMPONENT = [ + :scheme, + :userinfo, :host, :port, + :path, :typecode + ].freeze + + # + # Typecode is "a", "i", or "d". + # + # * "a" indicates a text file (the FTP command was ASCII) + # * "i" indicates a binary file (FTP command IMAGE) + # * "d" indicates the contents of a directory should be displayed + # + TYPECODE = ['a', 'i', 'd'].freeze + + # Typecode prefix ";type=". + TYPECODE_PREFIX = ';type='.freeze + + def self.new2(user, password, host, port, path, + typecode = nil, arg_check = true) # :nodoc: + # Do not use this method! Not tested. [Bug #7301] + # This methods remains just for compatibility, + # Keep it undocumented until the active maintainer is assigned. + typecode = nil if typecode.size == 0 + if typecode && !TYPECODE.include?(typecode) + raise ArgumentError, + "bad typecode is specified: #{typecode}" + end + + # do escape + + self.new('ftp', + [user, password], + host, port, nil, + typecode ? path + TYPECODE_PREFIX + typecode : path, + nil, nil, nil, arg_check) + end + + # + # == Description + # + # Creates a new Bundler::URI::FTP object from components, with syntax checking. + # + # The components accepted are +userinfo+, +host+, +port+, +path+, and + # +typecode+. + # + # The components should be provided either as an Array, or as a Hash + # with keys formed by preceding the component names with a colon. + # + # If an Array is used, the components must be passed in the + # order [userinfo, host, port, path, typecode]. + # + # If the path supplied is absolute, it will be escaped in order to + # make it absolute in the Bundler::URI. + # + # Examples: + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri1 = Bundler::URI::FTP.build(['user:password', 'ftp.example.com', nil, + # '/path/file.zip', 'i']) + # uri1.to_s # => "ftp://user:password@ftp.example.com/%2Fpath/file.zip;type=i" + # + # uri2 = Bundler::URI::FTP.build({:host => 'ftp.example.com', + # :path => 'ruby/src'}) + # uri2.to_s # => "ftp://ftp.example.com/ruby/src" + # + def self.build(args) + + # Fix the incoming path to be generic URL syntax + # FTP path -> URL path + # foo/bar /foo/bar + # /foo/bar /%2Ffoo/bar + # + if args.kind_of?(Array) + args[3] = '/' + args[3].sub(/^\//, '%2F') + else + args[:path] = '/' + args[:path].sub(/^\//, '%2F') + end + + tmp = Util::make_components_hash(self, args) + + if tmp[:typecode] + if tmp[:typecode].size == 1 + tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode] + end + tmp[:path] << tmp[:typecode] + end + + return super(tmp) + end + + # + # == Description + # + # Creates a new Bundler::URI::FTP object from generic URL components with no + # syntax checking. + # + # Unlike build(), this method does not escape the path component as + # required by RFC1738; instead it is treated as per RFC2396. + # + # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+, + # +opaque+, +query+, and +fragment+, in that order. + # + def initialize(scheme, + userinfo, host, port, registry, + path, opaque, + query, + fragment, + parser = nil, + arg_check = false) + raise InvalidURIError unless path + path = path.sub(/^\//,'') + path.sub!(/^%2F/,'/') + super(scheme, userinfo, host, port, registry, path, opaque, + query, fragment, parser, arg_check) + @typecode = nil + if tmp = @path.index(TYPECODE_PREFIX) + typecode = @path[tmp + TYPECODE_PREFIX.size..-1] + @path = @path[0..tmp - 1] + + if arg_check + self.typecode = typecode + else + self.set_typecode(typecode) + end + end + end + + # typecode accessor. + # + # See Bundler::URI::FTP::COMPONENT. + attr_reader :typecode + + # Validates typecode +v+, + # returns +true+ or +false+. + # + def check_typecode(v) + if TYPECODE.include?(v) + return true + else + raise InvalidComponentError, + "bad typecode(expected #{TYPECODE.join(', ')}): #{v}" + end + end + private :check_typecode + + # Private setter for the typecode +v+. + # + # See also Bundler::URI::FTP.typecode=. + # + def set_typecode(v) + @typecode = v + end + protected :set_typecode + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the typecode +v+ + # (with validation). + # + # See also Bundler::URI::FTP.check_typecode. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("ftp://john@ftp.example.com/my_file.img") + # #=> # + # uri.typecode = "i" + # uri + # #=> # + # + def typecode=(typecode) + check_typecode(typecode) + set_typecode(typecode) + typecode + end + + def merge(oth) # :nodoc: + tmp = super(oth) + if self != tmp + tmp.set_typecode(oth.typecode) + end + + return tmp + end + + # Returns the path from an FTP Bundler::URI. + # + # RFC 1738 specifically states that the path for an FTP Bundler::URI does not + # include the / which separates the Bundler::URI path from the Bundler::URI host. Example: + # + # ftp://ftp.example.com/pub/ruby + # + # The above Bundler::URI indicates that the client should connect to + # ftp.example.com then cd to pub/ruby from the initial login directory. + # + # If you want to cd to an absolute directory, you must include an + # escaped / (%2F) in the path. Example: + # + # ftp://ftp.example.com/%2Fpub/ruby + # + # This method will then return "/pub/ruby". + # + def path + return @path.sub(/^\//,'').sub(/^%2F/,'/') + end + + # Private setter for the path of the Bundler::URI::FTP. + def set_path(v) + super("/" + v.sub(/^\//, "%2F")) + end + protected :set_path + + # Returns a String representation of the Bundler::URI::FTP. + def to_s + save_path = nil + if @typecode + save_path = @path + @path = @path + TYPECODE_PREFIX + @typecode + end + str = super + if @typecode + @path = save_path + end + + return str + end + end + @@schemes['FTP'] = FTP +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/generic.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/generic.rb new file mode 100644 index 0000000..f29ba6c --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/generic.rb @@ -0,0 +1,1567 @@ +# frozen_string_literal: true + +# = uri/generic.rb +# +# Author:: Akira Yamada +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +require_relative 'common' +autoload :IPSocket, 'socket' +autoload :IPAddr, 'ipaddr' + +module Bundler::URI + + # + # Base class for all Bundler::URI classes. + # Implements generic Bundler::URI syntax as per RFC 2396. + # + class Generic + include Bundler::URI + + # + # A Default port of nil for Bundler::URI::Generic. + # + DEFAULT_PORT = nil + + # + # Returns default port. + # + def self.default_port + self::DEFAULT_PORT + end + + # + # Returns default port. + # + def default_port + self.class.default_port + end + + # + # An Array of the available components for Bundler::URI::Generic. + # + COMPONENT = [ + :scheme, + :userinfo, :host, :port, :registry, + :path, :opaque, + :query, + :fragment + ].freeze + + # + # Components of the Bundler::URI in the order. + # + def self.component + self::COMPONENT + end + + USE_REGISTRY = false # :nodoc: + + def self.use_registry # :nodoc: + self::USE_REGISTRY + end + + # + # == Synopsis + # + # See ::new. + # + # == Description + # + # At first, tries to create a new Bundler::URI::Generic instance using + # Bundler::URI::Generic::build. But, if exception Bundler::URI::InvalidComponentError is raised, + # then it does Bundler::URI::Escape.escape all Bundler::URI components and tries again. + # + def self.build2(args) + begin + return self.build(args) + rescue InvalidComponentError + if args.kind_of?(Array) + return self.build(args.collect{|x| + if x.is_a?(String) + DEFAULT_PARSER.escape(x) + else + x + end + }) + elsif args.kind_of?(Hash) + tmp = {} + args.each do |key, value| + tmp[key] = if value + DEFAULT_PARSER.escape(value) + else + value + end + end + return self.build(tmp) + end + end + end + + # + # == Synopsis + # + # See ::new. + # + # == Description + # + # Creates a new Bundler::URI::Generic instance from components of Bundler::URI::Generic + # with check. Components are: scheme, userinfo, host, port, registry, path, + # opaque, query, and fragment. You can provide arguments either by an Array or a Hash. + # See ::new for hash keys to use or for order of array items. + # + def self.build(args) + if args.kind_of?(Array) && + args.size == ::Bundler::URI::Generic::COMPONENT.size + tmp = args.dup + elsif args.kind_of?(Hash) + tmp = ::Bundler::URI::Generic::COMPONENT.collect do |c| + if args.include?(c) + args[c] + else + nil + end + end + else + component = self.class.component rescue ::Bundler::URI::Generic::COMPONENT + raise ArgumentError, + "expected Array of or Hash of components of #{self.class} (#{component.join(', ')})" + end + + tmp << nil + tmp << true + return self.new(*tmp) + end + + # + # == Args + # + # +scheme+:: + # Protocol scheme, i.e. 'http','ftp','mailto' and so on. + # +userinfo+:: + # User name and password, i.e. 'sdmitry:bla'. + # +host+:: + # Server host name. + # +port+:: + # Server port. + # +registry+:: + # Registry of naming authorities. + # +path+:: + # Path on server. + # +opaque+:: + # Opaque part. + # +query+:: + # Query data. + # +fragment+:: + # Part of the Bundler::URI after '#' character. + # +parser+:: + # Parser for internal use [Bundler::URI::DEFAULT_PARSER by default]. + # +arg_check+:: + # Check arguments [false by default]. + # + # == Description + # + # Creates a new Bundler::URI::Generic instance from ``generic'' components without check. + # + def initialize(scheme, + userinfo, host, port, registry, + path, opaque, + query, + fragment, + parser = DEFAULT_PARSER, + arg_check = false) + @scheme = nil + @user = nil + @password = nil + @host = nil + @port = nil + @path = nil + @query = nil + @opaque = nil + @fragment = nil + @parser = parser == DEFAULT_PARSER ? nil : parser + + if arg_check + self.scheme = scheme + self.userinfo = userinfo + self.hostname = host + self.port = port + self.path = path + self.query = query + self.opaque = opaque + self.fragment = fragment + else + self.set_scheme(scheme) + self.set_userinfo(userinfo) + self.set_host(host) + self.set_port(port) + self.set_path(path) + self.query = query + self.set_opaque(opaque) + self.fragment=(fragment) + end + if registry + raise InvalidURIError, + "the scheme #{@scheme} does not accept registry part: #{registry} (or bad hostname?)" + end + + @scheme&.freeze + self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2) + self.set_port(self.default_port) if self.default_port && !@port + end + + # + # Returns the scheme component of the Bundler::URI. + # + # Bundler::URI("http://foo/bar/baz").scheme #=> "http" + # + attr_reader :scheme + + # Returns the host component of the Bundler::URI. + # + # Bundler::URI("http://foo/bar/baz").host #=> "foo" + # + # It returns nil if no host component exists. + # + # Bundler::URI("mailto:foo@example.org").host #=> nil + # + # The component does not contain the port number. + # + # Bundler::URI("http://foo:8080/bar/baz").host #=> "foo" + # + # Since IPv6 addresses are wrapped with brackets in URIs, + # this method returns IPv6 addresses wrapped with brackets. + # This form is not appropriate to pass to socket methods such as TCPSocket.open. + # If unwrapped host names are required, use the #hostname method. + # + # Bundler::URI("http://[::1]/bar/baz").host #=> "[::1]" + # Bundler::URI("http://[::1]/bar/baz").hostname #=> "::1" + # + attr_reader :host + + # Returns the port component of the Bundler::URI. + # + # Bundler::URI("http://foo/bar/baz").port #=> 80 + # Bundler::URI("http://foo:8080/bar/baz").port #=> 8080 + # + attr_reader :port + + def registry # :nodoc: + nil + end + + # Returns the path component of the Bundler::URI. + # + # Bundler::URI("http://foo/bar/baz").path #=> "/bar/baz" + # + attr_reader :path + + # Returns the query component of the Bundler::URI. + # + # Bundler::URI("http://foo/bar/baz?search=FooBar").query #=> "search=FooBar" + # + attr_reader :query + + # Returns the opaque part of the Bundler::URI. + # + # Bundler::URI("mailto:foo@example.org").opaque #=> "foo@example.org" + # Bundler::URI("http://foo/bar/baz").opaque #=> nil + # + # The portion of the path that does not make use of the slash '/'. + # The path typically refers to an absolute path or an opaque part. + # (See RFC2396 Section 3 and 5.2.) + # + attr_reader :opaque + + # Returns the fragment component of the Bundler::URI. + # + # Bundler::URI("http://foo/bar/baz?search=FooBar#ponies").fragment #=> "ponies" + # + attr_reader :fragment + + # Returns the parser to be used. + # + # Unless a Bundler::URI::Parser is defined, DEFAULT_PARSER is used. + # + def parser + if !defined?(@parser) || !@parser + DEFAULT_PARSER + else + @parser || DEFAULT_PARSER + end + end + + # Replaces self by other Bundler::URI object. + # + def replace!(oth) + if self.class != oth.class + raise ArgumentError, "expected #{self.class} object" + end + + component.each do |c| + self.__send__("#{c}=", oth.__send__(c)) + end + end + private :replace! + + # + # Components of the Bundler::URI in the order. + # + def component + self.class.component + end + + # + # Checks the scheme +v+ component against the Bundler::URI::Parser Regexp for :SCHEME. + # + def check_scheme(v) + if v && parser.regexp[:SCHEME] !~ v + raise InvalidComponentError, + "bad component(expected scheme component): #{v}" + end + + return true + end + private :check_scheme + + # Protected setter for the scheme component +v+. + # + # See also Bundler::URI::Generic.scheme=. + # + def set_scheme(v) + @scheme = v&.downcase + end + protected :set_scheme + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the scheme component +v+ + # (with validation). + # + # See also Bundler::URI::Generic.check_scheme. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com") + # uri.scheme = "https" + # uri.to_s #=> "https://my.example.com" + # + def scheme=(v) + check_scheme(v) + set_scheme(v) + v + end + + # + # Checks the +user+ and +password+. + # + # If +password+ is not provided, then +user+ is + # split, using Bundler::URI::Generic.split_userinfo, to + # pull +user+ and +password. + # + # See also Bundler::URI::Generic.check_user, Bundler::URI::Generic.check_password. + # + def check_userinfo(user, password = nil) + if !password + user, password = split_userinfo(user) + end + check_user(user) + check_password(password, user) + + return true + end + private :check_userinfo + + # + # Checks the user +v+ component for RFC2396 compliance + # and against the Bundler::URI::Parser Regexp for :USERINFO. + # + # Can not have a registry or opaque component defined, + # with a user component defined. + # + def check_user(v) + if @opaque + raise InvalidURIError, + "can not set user with opaque" + end + + return v unless v + + if parser.regexp[:USERINFO] !~ v + raise InvalidComponentError, + "bad component(expected userinfo component or user component): #{v}" + end + + return true + end + private :check_user + + # + # Checks the password +v+ component for RFC2396 compliance + # and against the Bundler::URI::Parser Regexp for :USERINFO. + # + # Can not have a registry or opaque component defined, + # with a user component defined. + # + def check_password(v, user = @user) + if @opaque + raise InvalidURIError, + "can not set password with opaque" + end + return v unless v + + if !user + raise InvalidURIError, + "password component depends user component" + end + + if parser.regexp[:USERINFO] !~ v + raise InvalidComponentError, + "bad password component" + end + + return true + end + private :check_password + + # + # Sets userinfo, argument is string like 'name:pass'. + # + def userinfo=(userinfo) + if userinfo.nil? + return nil + end + check_userinfo(*userinfo) + set_userinfo(*userinfo) + # returns userinfo + end + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the +user+ component + # (with validation). + # + # See also Bundler::URI::Generic.check_user. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://john:S3nsit1ve@my.example.com") + # uri.user = "sam" + # uri.to_s #=> "http://sam:V3ry_S3nsit1ve@my.example.com" + # + def user=(user) + check_user(user) + set_user(user) + # returns user + end + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the +password+ component + # (with validation). + # + # See also Bundler::URI::Generic.check_password. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://john:S3nsit1ve@my.example.com") + # uri.password = "V3ry_S3nsit1ve" + # uri.to_s #=> "http://john:V3ry_S3nsit1ve@my.example.com" + # + def password=(password) + check_password(password) + set_password(password) + # returns password + end + + # Protected setter for the +user+ component, and +password+ if available + # (with validation). + # + # See also Bundler::URI::Generic.userinfo=. + # + def set_userinfo(user, password = nil) + unless password + user, password = split_userinfo(user) + end + @user = user + @password = password if password + + [@user, @password] + end + protected :set_userinfo + + # Protected setter for the user component +v+. + # + # See also Bundler::URI::Generic.user=. + # + def set_user(v) + set_userinfo(v, @password) + v + end + protected :set_user + + # Protected setter for the password component +v+. + # + # See also Bundler::URI::Generic.password=. + # + def set_password(v) + @password = v + # returns v + end + protected :set_password + + # Returns the userinfo +ui+ as [user, password] + # if properly formatted as 'user:password'. + def split_userinfo(ui) + return nil, nil unless ui + user, password = ui.split(':', 2) + + return user, password + end + private :split_userinfo + + # Escapes 'user:password' +v+ based on RFC 1738 section 3.1. + def escape_userpass(v) + parser.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/ + end + private :escape_userpass + + # Returns the userinfo, either as 'user' or 'user:password'. + def userinfo + if @user.nil? + nil + elsif @password.nil? + @user + else + @user + ':' + @password + end + end + + # Returns the user component. + def user + @user + end + + # Returns the password component. + def password + @password + end + + # + # Checks the host +v+ component for RFC2396 compliance + # and against the Bundler::URI::Parser Regexp for :HOST. + # + # Can not have a registry or opaque component defined, + # with a host component defined. + # + def check_host(v) + return v unless v + + if @opaque + raise InvalidURIError, + "can not set host with registry or opaque" + elsif parser.regexp[:HOST] !~ v + raise InvalidComponentError, + "bad component(expected host component): #{v}" + end + + return true + end + private :check_host + + # Protected setter for the host component +v+. + # + # See also Bundler::URI::Generic.host=. + # + def set_host(v) + @host = v + end + protected :set_host + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the host component +v+ + # (with validation). + # + # See also Bundler::URI::Generic.check_host. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com") + # uri.host = "foo.com" + # uri.to_s #=> "http://foo.com" + # + def host=(v) + check_host(v) + set_host(v) + v + end + + # Extract the host part of the Bundler::URI and unwrap brackets for IPv6 addresses. + # + # This method is the same as Bundler::URI::Generic#host except + # brackets for IPv6 (and future IP) addresses are removed. + # + # uri = Bundler::URI("http://[::1]/bar") + # uri.hostname #=> "::1" + # uri.host #=> "[::1]" + # + def hostname + v = self.host + /\A\[(.*)\]\z/ =~ v ? $1 : v + end + + # Sets the host part of the Bundler::URI as the argument with brackets for IPv6 addresses. + # + # This method is the same as Bundler::URI::Generic#host= except + # the argument can be a bare IPv6 address. + # + # uri = Bundler::URI("http://foo/bar") + # uri.hostname = "::1" + # uri.to_s #=> "http://[::1]/bar" + # + # If the argument seems to be an IPv6 address, + # it is wrapped with brackets. + # + def hostname=(v) + v = "[#{v}]" if /\A\[.*\]\z/ !~ v && /:/ =~ v + self.host = v + end + + # + # Checks the port +v+ component for RFC2396 compliance + # and against the Bundler::URI::Parser Regexp for :PORT. + # + # Can not have a registry or opaque component defined, + # with a port component defined. + # + def check_port(v) + return v unless v + + if @opaque + raise InvalidURIError, + "can not set port with registry or opaque" + elsif !v.kind_of?(Integer) && parser.regexp[:PORT] !~ v + raise InvalidComponentError, + "bad component(expected port component): #{v.inspect}" + end + + return true + end + private :check_port + + # Protected setter for the port component +v+. + # + # See also Bundler::URI::Generic.port=. + # + def set_port(v) + v = v.empty? ? nil : v.to_i unless !v || v.kind_of?(Integer) + @port = v + end + protected :set_port + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the port component +v+ + # (with validation). + # + # See also Bundler::URI::Generic.check_port. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com") + # uri.port = 8080 + # uri.to_s #=> "http://my.example.com:8080" + # + def port=(v) + check_port(v) + set_port(v) + port + end + + def check_registry(v) # :nodoc: + raise InvalidURIError, "can not set registry" + end + private :check_registry + + def set_registry(v) #:nodoc: + raise InvalidURIError, "can not set registry" + end + protected :set_registry + + def registry=(v) + raise InvalidURIError, "can not set registry" + end + + # + # Checks the path +v+ component for RFC2396 compliance + # and against the Bundler::URI::Parser Regexp + # for :ABS_PATH and :REL_PATH. + # + # Can not have a opaque component defined, + # with a path component defined. + # + def check_path(v) + # raise if both hier and opaque are not nil, because: + # absoluteURI = scheme ":" ( hier_part | opaque_part ) + # hier_part = ( net_path | abs_path ) [ "?" query ] + if v && @opaque + raise InvalidURIError, + "path conflicts with opaque" + end + + # If scheme is ftp, path may be relative. + # See RFC 1738 section 3.2.2, and RFC 2396. + if @scheme && @scheme != "ftp" + if v && v != '' && parser.regexp[:ABS_PATH] !~ v + raise InvalidComponentError, + "bad component(expected absolute path component): #{v}" + end + else + if v && v != '' && parser.regexp[:ABS_PATH] !~ v && + parser.regexp[:REL_PATH] !~ v + raise InvalidComponentError, + "bad component(expected relative path component): #{v}" + end + end + + return true + end + private :check_path + + # Protected setter for the path component +v+. + # + # See also Bundler::URI::Generic.path=. + # + def set_path(v) + @path = v + end + protected :set_path + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the path component +v+ + # (with validation). + # + # See also Bundler::URI::Generic.check_path. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com/pub/files") + # uri.path = "/faq/" + # uri.to_s #=> "http://my.example.com/faq/" + # + def path=(v) + check_path(v) + set_path(v) + v + end + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the query component +v+. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com/?id=25") + # uri.query = "id=1" + # uri.to_s #=> "http://my.example.com/?id=1" + # + def query=(v) + return @query = nil unless v + raise InvalidURIError, "query conflicts with opaque" if @opaque + + x = v.to_str + v = x.dup if x.equal? v + v.encode!(Encoding::UTF_8) rescue nil + v.delete!("\t\r\n") + v.force_encoding(Encoding::ASCII_8BIT) + raise InvalidURIError, "invalid percent escape: #{$1}" if /(%\H\H)/n.match(v) + v.gsub!(/(?!%\h\h|[!$-&(-;=?-_a-~])./n.freeze){'%%%02X' % $&.ord} + v.force_encoding(Encoding::US_ASCII) + @query = v + end + + # + # Checks the opaque +v+ component for RFC2396 compliance and + # against the Bundler::URI::Parser Regexp for :OPAQUE. + # + # Can not have a host, port, user, or path component defined, + # with an opaque component defined. + # + def check_opaque(v) + return v unless v + + # raise if both hier and opaque are not nil, because: + # absoluteURI = scheme ":" ( hier_part | opaque_part ) + # hier_part = ( net_path | abs_path ) [ "?" query ] + if @host || @port || @user || @path # userinfo = @user + ':' + @password + raise InvalidURIError, + "can not set opaque with host, port, userinfo or path" + elsif v && parser.regexp[:OPAQUE] !~ v + raise InvalidComponentError, + "bad component(expected opaque component): #{v}" + end + + return true + end + private :check_opaque + + # Protected setter for the opaque component +v+. + # + # See also Bundler::URI::Generic.opaque=. + # + def set_opaque(v) + @opaque = v + end + protected :set_opaque + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the opaque component +v+ + # (with validation). + # + # See also Bundler::URI::Generic.check_opaque. + # + def opaque=(v) + check_opaque(v) + set_opaque(v) + v + end + + # + # Checks the fragment +v+ component against the Bundler::URI::Parser Regexp for :FRAGMENT. + # + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the fragment component +v+ + # (with validation). + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com/?id=25#time=1305212049") + # uri.fragment = "time=1305212086" + # uri.to_s #=> "http://my.example.com/?id=25#time=1305212086" + # + def fragment=(v) + return @fragment = nil unless v + + x = v.to_str + v = x.dup if x.equal? v + v.encode!(Encoding::UTF_8) rescue nil + v.delete!("\t\r\n") + v.force_encoding(Encoding::ASCII_8BIT) + v.gsub!(/(?!%\h\h|[!-~])./n){'%%%02X' % $&.ord} + v.force_encoding(Encoding::US_ASCII) + @fragment = v + end + + # + # Returns true if Bundler::URI is hierarchical. + # + # == Description + # + # Bundler::URI has components listed in order of decreasing significance from left to right, + # see RFC3986 https://tools.ietf.org/html/rfc3986 1.2.3. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com/") + # uri.hierarchical? + # #=> true + # uri = Bundler::URI.parse("mailto:joe@example.com") + # uri.hierarchical? + # #=> false + # + def hierarchical? + if @path + true + else + false + end + end + + # + # Returns true if Bundler::URI has a scheme (e.g. http:// or https://) specified. + # + def absolute? + if @scheme + true + else + false + end + end + alias absolute absolute? + + # + # Returns true if Bundler::URI does not have a scheme (e.g. http:// or https://) specified. + # + def relative? + !absolute? + end + + # + # Returns an Array of the path split on '/'. + # + def split_path(path) + path.split("/", -1) + end + private :split_path + + # + # Merges a base path +base+, with relative path +rel+, + # returns a modified base path. + # + def merge_path(base, rel) + + # RFC2396, Section 5.2, 5) + # RFC2396, Section 5.2, 6) + base_path = split_path(base) + rel_path = split_path(rel) + + # RFC2396, Section 5.2, 6), a) + base_path << '' if base_path.last == '..' + while i = base_path.index('..') + base_path.slice!(i - 1, 2) + end + + if (first = rel_path.first) and first.empty? + base_path.clear + rel_path.shift + end + + # RFC2396, Section 5.2, 6), c) + # RFC2396, Section 5.2, 6), d) + rel_path.push('') if rel_path.last == '.' || rel_path.last == '..' + rel_path.delete('.') + + # RFC2396, Section 5.2, 6), e) + tmp = [] + rel_path.each do |x| + if x == '..' && + !(tmp.empty? || tmp.last == '..') + tmp.pop + else + tmp << x + end + end + + add_trailer_slash = !tmp.empty? + if base_path.empty? + base_path = [''] # keep '/' for root directory + elsif add_trailer_slash + base_path.pop + end + while x = tmp.shift + if x == '..' + # RFC2396, Section 4 + # a .. or . in an absolute path has no special meaning + base_path.pop if base_path.size > 1 + else + # if x == '..' + # valid absolute (but abnormal) path "/../..." + # else + # valid absolute path + # end + base_path << x + tmp.each {|t| base_path << t} + add_trailer_slash = false + break + end + end + base_path.push('') if add_trailer_slash + + return base_path.join('/') + end + private :merge_path + + # + # == Args + # + # +oth+:: + # Bundler::URI or String + # + # == Description + # + # Destructive form of #merge. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com") + # uri.merge!("/main.rbx?page=1") + # uri.to_s # => "http://my.example.com/main.rbx?page=1" + # + def merge!(oth) + t = merge(oth) + if self == t + nil + else + replace!(t) + self + end + end + + # + # == Args + # + # +oth+:: + # Bundler::URI or String + # + # == Description + # + # Merges two URIs. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com") + # uri.merge("/main.rbx?page=1") + # # => "http://my.example.com/main.rbx?page=1" + # + def merge(oth) + rel = parser.__send__(:convert_to_uri, oth) + + if rel.absolute? + #raise BadURIError, "both Bundler::URI are absolute" if absolute? + # hmm... should return oth for usability? + return rel + end + + unless self.absolute? + raise BadURIError, "both Bundler::URI are relative" + end + + base = self.dup + + authority = rel.userinfo || rel.host || rel.port + + # RFC2396, Section 5.2, 2) + if (rel.path.nil? || rel.path.empty?) && !authority && !rel.query + base.fragment=(rel.fragment) if rel.fragment + return base + end + + base.query = nil + base.fragment=(nil) + + # RFC2396, Section 5.2, 4) + if !authority + base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path + else + # RFC2396, Section 5.2, 4) + base.set_path(rel.path) if rel.path + end + + # RFC2396, Section 5.2, 7) + base.set_userinfo(rel.userinfo) if rel.userinfo + base.set_host(rel.host) if rel.host + base.set_port(rel.port) if rel.port + base.query = rel.query if rel.query + base.fragment=(rel.fragment) if rel.fragment + + return base + end # merge + alias + merge + + # :stopdoc: + def route_from_path(src, dst) + case dst + when src + # RFC2396, Section 4.2 + return '' + when %r{(?:\A|/)\.\.?(?:/|\z)} + # dst has abnormal absolute path, + # like "/./", "/../", "/x/../", ... + return dst.dup + end + + src_path = src.scan(%r{[^/]*/}) + dst_path = dst.scan(%r{[^/]*/?}) + + # discard same parts + while !dst_path.empty? && dst_path.first == src_path.first + src_path.shift + dst_path.shift + end + + tmp = dst_path.join + + # calculate + if src_path.empty? + if tmp.empty? + return './' + elsif dst_path.first.include?(':') # (see RFC2396 Section 5) + return './' + tmp + else + return tmp + end + end + + return '../' * src_path.size + tmp + end + private :route_from_path + # :startdoc: + + # :stopdoc: + def route_from0(oth) + oth = parser.__send__(:convert_to_uri, oth) + if self.relative? + raise BadURIError, + "relative Bundler::URI: #{self}" + end + if oth.relative? + raise BadURIError, + "relative Bundler::URI: #{oth}" + end + + if self.scheme != oth.scheme + return self, self.dup + end + rel = Bundler::URI::Generic.new(nil, # it is relative Bundler::URI + self.userinfo, self.host, self.port, + nil, self.path, self.opaque, + self.query, self.fragment, parser) + + if rel.userinfo != oth.userinfo || + rel.host.to_s.downcase != oth.host.to_s.downcase || + rel.port != oth.port + + if self.userinfo.nil? && self.host.nil? + return self, self.dup + end + + rel.set_port(nil) if rel.port == oth.default_port + return rel, rel + end + rel.set_userinfo(nil) + rel.set_host(nil) + rel.set_port(nil) + + if rel.path && rel.path == oth.path + rel.set_path('') + rel.query = nil if rel.query == oth.query + return rel, rel + elsif rel.opaque && rel.opaque == oth.opaque + rel.set_opaque('') + rel.query = nil if rel.query == oth.query + return rel, rel + end + + # you can modify `rel', but can not `oth'. + return oth, rel + end + private :route_from0 + # :startdoc: + + # + # == Args + # + # +oth+:: + # Bundler::URI or String + # + # == Description + # + # Calculates relative path from oth to self. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse('http://my.example.com/main.rbx?page=1') + # uri.route_from('http://my.example.com') + # #=> # + # + def route_from(oth) + # you can modify `rel', but can not `oth'. + begin + oth, rel = route_from0(oth) + rescue + raise $!.class, $!.message + end + if oth == rel + return rel + end + + rel.set_path(route_from_path(oth.path, self.path)) + if rel.path == './' && self.query + # "./?foo" -> "?foo" + rel.set_path('') + end + + return rel + end + + alias - route_from + + # + # == Args + # + # +oth+:: + # Bundler::URI or String + # + # == Description + # + # Calculates relative path to oth from self. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse('http://my.example.com') + # uri.route_to('http://my.example.com/main.rbx?page=1') + # #=> # + # + def route_to(oth) + parser.__send__(:convert_to_uri, oth).route_from(self) + end + + # + # Returns normalized Bundler::URI. + # + # require 'bundler/vendor/uri/lib/uri' + # + # Bundler::URI("HTTP://my.EXAMPLE.com").normalize + # #=> # + # + # Normalization here means: + # + # * scheme and host are converted to lowercase, + # * an empty path component is set to "/". + # + def normalize + uri = dup + uri.normalize! + uri + end + + # + # Destructive version of #normalize. + # + def normalize! + if path&.empty? + set_path('/') + end + if scheme && scheme != scheme.downcase + set_scheme(self.scheme.downcase) + end + if host && host != host.downcase + set_host(self.host.downcase) + end + end + + # + # Constructs String from Bundler::URI. + # + def to_s + str = ''.dup + if @scheme + str << @scheme + str << ':' + end + + if @opaque + str << @opaque + else + if @host || %w[file postgres].include?(@scheme) + str << '//' + end + if self.userinfo + str << self.userinfo + str << '@' + end + if @host + str << @host + end + if @port && @port != self.default_port + str << ':' + str << @port.to_s + end + str << @path + if @query + str << '?' + str << @query + end + end + if @fragment + str << '#' + str << @fragment + end + str + end + + # + # Compares two URIs. + # + def ==(oth) + if self.class == oth.class + self.normalize.component_ary == oth.normalize.component_ary + else + false + end + end + + def hash + self.component_ary.hash + end + + def eql?(oth) + self.class == oth.class && + parser == oth.parser && + self.component_ary.eql?(oth.component_ary) + end + +=begin + +--- Bundler::URI::Generic#===(oth) + +=end +# def ===(oth) +# raise NotImplementedError +# end + +=begin +=end + + + # Returns an Array of the components defined from the COMPONENT Array. + def component_ary + component.collect do |x| + self.__send__(x) + end + end + protected :component_ary + + # == Args + # + # +components+:: + # Multiple Symbol arguments defined in Bundler::URI::HTTP. + # + # == Description + # + # Selects specified components from Bundler::URI. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse('http://myuser:mypass@my.example.com/test.rbx') + # uri.select(:userinfo, :host, :path) + # # => ["myuser:mypass", "my.example.com", "/test.rbx"] + # + def select(*components) + components.collect do |c| + if component.include?(c) + self.__send__(c) + else + raise ArgumentError, + "expected of components of #{self.class} (#{self.class.component.join(', ')})" + end + end + end + + def inspect + "#<#{self.class} #{self}>" + end + + # + # == Args + # + # +v+:: + # Bundler::URI or String + # + # == Description + # + # Attempts to parse other Bundler::URI +oth+, + # returns [parsed_oth, self]. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com") + # uri.coerce("http://foo.com") + # #=> [#, #] + # + def coerce(oth) + case oth + when String + oth = parser.parse(oth) + else + super + end + + return oth, self + end + + # Returns a proxy Bundler::URI. + # The proxy Bundler::URI is obtained from environment variables such as http_proxy, + # ftp_proxy, no_proxy, etc. + # If there is no proper proxy, nil is returned. + # + # If the optional parameter +env+ is specified, it is used instead of ENV. + # + # Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.) + # are examined, too. + # + # But http_proxy and HTTP_PROXY is treated specially under CGI environment. + # It's because HTTP_PROXY may be set by Proxy: header. + # So HTTP_PROXY is not used. + # http_proxy is not used too if the variable is case insensitive. + # CGI_HTTP_PROXY can be used instead. + def find_proxy(env=ENV) + raise BadURIError, "relative Bundler::URI: #{self}" if self.relative? + name = self.scheme.downcase + '_proxy' + proxy_uri = nil + if name == 'http_proxy' && env.include?('REQUEST_METHOD') # CGI? + # HTTP_PROXY conflicts with *_proxy for proxy settings and + # HTTP_* for header information in CGI. + # So it should be careful to use it. + pairs = env.reject {|k, v| /\Ahttp_proxy\z/i !~ k } + case pairs.length + when 0 # no proxy setting anyway. + proxy_uri = nil + when 1 + k, _ = pairs.shift + if k == 'http_proxy' && env[k.upcase] == nil + # http_proxy is safe to use because ENV is case sensitive. + proxy_uri = env[name] + else + proxy_uri = nil + end + else # http_proxy is safe to use because ENV is case sensitive. + proxy_uri = env.to_hash[name] + end + if !proxy_uri + # Use CGI_HTTP_PROXY. cf. libwww-perl. + proxy_uri = env["CGI_#{name.upcase}"] + end + elsif name == 'http_proxy' + unless proxy_uri = env[name] + if proxy_uri = env[name.upcase] + warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.', uplevel: 1 + end + end + else + proxy_uri = env[name] || env[name.upcase] + end + + if proxy_uri.nil? || proxy_uri.empty? + return nil + end + + if self.hostname + begin + addr = IPSocket.getaddress(self.hostname) + return nil if /\A127\.|\A::1\z/ =~ addr + rescue SocketError + end + end + + name = 'no_proxy' + if no_proxy = env[name] || env[name.upcase] + return nil unless Bundler::URI::Generic.use_proxy?(self.hostname, addr, self.port, no_proxy) + end + Bundler::URI.parse(proxy_uri) + end + + def self.use_proxy?(hostname, addr, port, no_proxy) # :nodoc: + hostname = hostname.downcase + dothostname = ".#{hostname}" + no_proxy.scan(/([^:,\s]+)(?::(\d+))?/) {|p_host, p_port| + if !p_port || port == p_port.to_i + if p_host.start_with?('.') + return false if hostname.end_with?(p_host.downcase) + else + return false if dothostname.end_with?(".#{p_host.downcase}") + end + if addr + begin + return false if IPAddr.new(p_host).include?(addr) + rescue IPAddr::InvalidAddressError + next + end + end + end + } + true + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/http.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/http.rb new file mode 100644 index 0000000..50d7e42 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/http.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: false +# = uri/http.rb +# +# Author:: Akira Yamada +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +require_relative 'generic' + +module Bundler::URI + + # + # The syntax of HTTP URIs is defined in RFC1738 section 3.3. + # + # Note that the Ruby Bundler::URI library allows HTTP URLs containing usernames and + # passwords. This is not legal as per the RFC, but used to be + # supported in Internet Explorer 5 and 6, before the MS04-004 security + # update. See . + # + class HTTP < Generic + # A Default port of 80 for Bundler::URI::HTTP. + DEFAULT_PORT = 80 + + # An Array of the available components for Bundler::URI::HTTP. + COMPONENT = %i[ + scheme + userinfo host port + path + query + fragment + ].freeze + + # + # == Description + # + # Creates a new Bundler::URI::HTTP object from components, with syntax checking. + # + # The components accepted are userinfo, host, port, path, query, and + # fragment. + # + # The components should be provided either as an Array, or as a Hash + # with keys formed by preceding the component names with a colon. + # + # If an Array is used, the components must be passed in the + # order [userinfo, host, port, path, query, fragment]. + # + # Example: + # + # uri = Bundler::URI::HTTP.build(host: 'www.example.com', path: '/foo/bar') + # + # uri = Bundler::URI::HTTP.build([nil, "www.example.com", nil, "/path", + # "query", 'fragment']) + # + # Currently, if passed userinfo components this method generates + # invalid HTTP URIs as per RFC 1738. + # + def self.build(args) + tmp = Util.make_components_hash(self, args) + super(tmp) + end + + # + # == Description + # + # Returns the full path for an HTTP request, as required by Net::HTTP::Get. + # + # If the Bundler::URI contains a query, the full path is Bundler::URI#path + '?' + Bundler::URI#query. + # Otherwise, the path is simply Bundler::URI#path. + # + # Example: + # + # uri = Bundler::URI::HTTP.build(path: '/foo/bar', query: 'test=true') + # uri.request_uri # => "/foo/bar?test=true" + # + def request_uri + return unless @path + + url = @query ? "#@path?#@query" : @path.dup + url.start_with?(?/.freeze) ? url : ?/ + url + end + end + + @@schemes['HTTP'] = HTTP + +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/https.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/https.rb new file mode 100644 index 0000000..4fd4e9a --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/https.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: false +# = uri/https.rb +# +# Author:: Akira Yamada +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +require_relative 'http' + +module Bundler::URI + + # The default port for HTTPS URIs is 443, and the scheme is 'https:' rather + # than 'http:'. Other than that, HTTPS URIs are identical to HTTP URIs; + # see Bundler::URI::HTTP. + class HTTPS < HTTP + # A Default port of 443 for Bundler::URI::HTTPS + DEFAULT_PORT = 443 + end + @@schemes['HTTPS'] = HTTPS +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/ldap.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/ldap.rb new file mode 100644 index 0000000..6e9e191 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/ldap.rb @@ -0,0 +1,261 @@ +# frozen_string_literal: false +# = uri/ldap.rb +# +# Author:: +# Takaaki Tateishi +# Akira Yamada +# License:: +# Bundler::URI::LDAP is copyrighted free software by Takaaki Tateishi and Akira Yamada. +# You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +require_relative 'generic' + +module Bundler::URI + + # + # LDAP Bundler::URI SCHEMA (described in RFC2255). + #-- + # ldap:///[?[?[?[?]]]] + #++ + class LDAP < Generic + + # A Default port of 389 for Bundler::URI::LDAP. + DEFAULT_PORT = 389 + + # An Array of the available components for Bundler::URI::LDAP. + COMPONENT = [ + :scheme, + :host, :port, + :dn, + :attributes, + :scope, + :filter, + :extensions, + ].freeze + + # Scopes available for the starting point. + # + # * SCOPE_BASE - the Base DN + # * SCOPE_ONE - one level under the Base DN, not including the base DN and + # not including any entries under this + # * SCOPE_SUB - subtrees, all entries at all levels + # + SCOPE = [ + SCOPE_ONE = 'one', + SCOPE_SUB = 'sub', + SCOPE_BASE = 'base', + ].freeze + + # + # == Description + # + # Creates a new Bundler::URI::LDAP object from components, with syntax checking. + # + # The components accepted are host, port, dn, attributes, + # scope, filter, and extensions. + # + # The components should be provided either as an Array, or as a Hash + # with keys formed by preceding the component names with a colon. + # + # If an Array is used, the components must be passed in the + # order [host, port, dn, attributes, scope, filter, extensions]. + # + # Example: + # + # uri = Bundler::URI::LDAP.build({:host => 'ldap.example.com', + # :dn => '/dc=example'}) + # + # uri = Bundler::URI::LDAP.build(["ldap.example.com", nil, + # "/dc=example;dc=com", "query", nil, nil, nil]) + # + def self.build(args) + tmp = Util::make_components_hash(self, args) + + if tmp[:dn] + tmp[:path] = tmp[:dn] + end + + query = [] + [:extensions, :filter, :scope, :attributes].collect do |x| + next if !tmp[x] && query.size == 0 + query.unshift(tmp[x]) + end + + tmp[:query] = query.join('?') + + return super(tmp) + end + + # + # == Description + # + # Creates a new Bundler::URI::LDAP object from generic Bundler::URI components as per + # RFC 2396. No LDAP-specific syntax checking is performed. + # + # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+, + # +opaque+, +query+, and +fragment+, in that order. + # + # Example: + # + # uri = Bundler::URI::LDAP.new("ldap", nil, "ldap.example.com", nil, nil, + # "/dc=example;dc=com", nil, "query", nil) + # + # See also Bundler::URI::Generic.new. + # + def initialize(*arg) + super(*arg) + + if @fragment + raise InvalidURIError, 'bad LDAP URL' + end + + parse_dn + parse_query + end + + # Private method to cleanup +dn+ from using the +path+ component attribute. + def parse_dn + raise InvalidURIError, 'bad LDAP URL' unless @path + @dn = @path[1..-1] + end + private :parse_dn + + # Private method to cleanup +attributes+, +scope+, +filter+, and +extensions+ + # from using the +query+ component attribute. + def parse_query + @attributes = nil + @scope = nil + @filter = nil + @extensions = nil + + if @query + attrs, scope, filter, extensions = @query.split('?') + + @attributes = attrs if attrs && attrs.size > 0 + @scope = scope if scope && scope.size > 0 + @filter = filter if filter && filter.size > 0 + @extensions = extensions if extensions && extensions.size > 0 + end + end + private :parse_query + + # Private method to assemble +query+ from +attributes+, +scope+, +filter+, and +extensions+. + def build_path_query + @path = '/' + @dn + + query = [] + [@extensions, @filter, @scope, @attributes].each do |x| + next if !x && query.size == 0 + query.unshift(x) + end + @query = query.join('?') + end + private :build_path_query + + # Returns dn. + def dn + @dn + end + + # Private setter for dn +val+. + def set_dn(val) + @dn = val + build_path_query + @dn + end + protected :set_dn + + # Setter for dn +val+. + def dn=(val) + set_dn(val) + val + end + + # Returns attributes. + def attributes + @attributes + end + + # Private setter for attributes +val+. + def set_attributes(val) + @attributes = val + build_path_query + @attributes + end + protected :set_attributes + + # Setter for attributes +val+. + def attributes=(val) + set_attributes(val) + val + end + + # Returns scope. + def scope + @scope + end + + # Private setter for scope +val+. + def set_scope(val) + @scope = val + build_path_query + @scope + end + protected :set_scope + + # Setter for scope +val+. + def scope=(val) + set_scope(val) + val + end + + # Returns filter. + def filter + @filter + end + + # Private setter for filter +val+. + def set_filter(val) + @filter = val + build_path_query + @filter + end + protected :set_filter + + # Setter for filter +val+. + def filter=(val) + set_filter(val) + val + end + + # Returns extensions. + def extensions + @extensions + end + + # Private setter for extensions +val+. + def set_extensions(val) + @extensions = val + build_path_query + @extensions + end + protected :set_extensions + + # Setter for extensions +val+. + def extensions=(val) + set_extensions(val) + val + end + + # Checks if Bundler::URI has a path. + # For Bundler::URI::LDAP this will return +false+. + def hierarchical? + false + end + end + + @@schemes['LDAP'] = LDAP +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/ldaps.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/ldaps.rb new file mode 100644 index 0000000..0af35bb --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/ldaps.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: false +# = uri/ldap.rb +# +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +require_relative 'ldap' + +module Bundler::URI + + # The default port for LDAPS URIs is 636, and the scheme is 'ldaps:' rather + # than 'ldap:'. Other than that, LDAPS URIs are identical to LDAP URIs; + # see Bundler::URI::LDAP. + class LDAPS < LDAP + # A Default port of 636 for Bundler::URI::LDAPS + DEFAULT_PORT = 636 + end + @@schemes['LDAPS'] = LDAPS +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/mailto.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/mailto.rb new file mode 100644 index 0000000..ff7ab7e --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/mailto.rb @@ -0,0 +1,293 @@ +# frozen_string_literal: false +# = uri/mailto.rb +# +# Author:: Akira Yamada +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +require_relative 'generic' + +module Bundler::URI + + # + # RFC6068, the mailto URL scheme. + # + class MailTo < Generic + include REGEXP + + # A Default port of nil for Bundler::URI::MailTo. + DEFAULT_PORT = nil + + # An Array of the available components for Bundler::URI::MailTo. + COMPONENT = [ :scheme, :to, :headers ].freeze + + # :stopdoc: + # "hname" and "hvalue" are encodings of an RFC 822 header name and + # value, respectively. As with "to", all URL reserved characters must + # be encoded. + # + # "#mailbox" is as specified in RFC 822 [RFC822]. This means that it + # consists of zero or more comma-separated mail addresses, possibly + # including "phrase" and "comment" components. Note that all URL + # reserved characters in "to" must be encoded: in particular, + # parentheses, commas, and the percent sign ("%"), which commonly occur + # in the "mailbox" syntax. + # + # Within mailto URLs, the characters "?", "=", "&" are reserved. + + # ; RFC 6068 + # hfields = "?" hfield *( "&" hfield ) + # hfield = hfname "=" hfvalue + # hfname = *qchar + # hfvalue = *qchar + # qchar = unreserved / pct-encoded / some-delims + # some-delims = "!" / "$" / "'" / "(" / ")" / "*" + # / "+" / "," / ";" / ":" / "@" + # + # ; RFC3986 + # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + # pct-encoded = "%" HEXDIG HEXDIG + HEADER_REGEXP = /\A(?(?:%\h\h|[!$'-.0-;@-Z_a-z~])*=(?:%\h\h|[!$'-.0-;@-Z_a-z~])*)(?:&\g)*\z/ + # practical regexp for email address + # https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address + EMAIL_REGEXP = /\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/ + # :startdoc: + + # + # == Description + # + # Creates a new Bundler::URI::MailTo object from components, with syntax checking. + # + # Components can be provided as an Array or Hash. If an Array is used, + # the components must be supplied as [to, headers]. + # + # If a Hash is used, the keys are the component names preceded by colons. + # + # The headers can be supplied as a pre-encoded string, such as + # "subject=subscribe&cc=address", or as an Array of Arrays + # like [['subject', 'subscribe'], ['cc', 'address']]. + # + # Examples: + # + # require 'bundler/vendor/uri/lib/uri' + # + # m1 = Bundler::URI::MailTo.build(['joe@example.com', 'subject=Ruby']) + # m1.to_s # => "mailto:joe@example.com?subject=Ruby" + # + # m2 = Bundler::URI::MailTo.build(['john@example.com', [['Subject', 'Ruby'], ['Cc', 'jack@example.com']]]) + # m2.to_s # => "mailto:john@example.com?Subject=Ruby&Cc=jack@example.com" + # + # m3 = Bundler::URI::MailTo.build({:to => 'listman@example.com', :headers => [['subject', 'subscribe']]}) + # m3.to_s # => "mailto:listman@example.com?subject=subscribe" + # + def self.build(args) + tmp = Util.make_components_hash(self, args) + + case tmp[:to] + when Array + tmp[:opaque] = tmp[:to].join(',') + when String + tmp[:opaque] = tmp[:to].dup + else + tmp[:opaque] = '' + end + + if tmp[:headers] + query = + case tmp[:headers] + when Array + tmp[:headers].collect { |x| + if x.kind_of?(Array) + x[0] + '=' + x[1..-1].join + else + x.to_s + end + }.join('&') + when Hash + tmp[:headers].collect { |h,v| + h + '=' + v + }.join('&') + else + tmp[:headers].to_s + end + unless query.empty? + tmp[:opaque] << '?' << query + end + end + + super(tmp) + end + + # + # == Description + # + # Creates a new Bundler::URI::MailTo object from generic URL components with + # no syntax checking. + # + # This method is usually called from Bundler::URI::parse, which checks + # the validity of each component. + # + def initialize(*arg) + super(*arg) + + @to = nil + @headers = [] + + # The RFC3986 parser does not normally populate opaque + @opaque = "?#{@query}" if @query && !@opaque + + unless @opaque + raise InvalidComponentError, + "missing opaque part for mailto URL" + end + to, header = @opaque.split('?', 2) + # allow semicolon as a addr-spec separator + # http://support.microsoft.com/kb/820868 + unless /\A(?:[^@,;]+@[^@,;]+(?:\z|[,;]))*\z/ =~ to + raise InvalidComponentError, + "unrecognised opaque part for mailtoURL: #{@opaque}" + end + + if arg[10] # arg_check + self.to = to + self.headers = header + else + set_to(to) + set_headers(header) + end + end + + # The primary e-mail address of the URL, as a String. + attr_reader :to + + # E-mail headers set by the URL, as an Array of Arrays. + attr_reader :headers + + # Checks the to +v+ component. + def check_to(v) + return true unless v + return true if v.size == 0 + + v.split(/[,;]/).each do |addr| + # check url safety as path-rootless + if /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*\z/ !~ addr + raise InvalidComponentError, + "an address in 'to' is invalid as Bundler::URI #{addr.dump}" + end + + # check addr-spec + # don't s/\+/ /g + addr.gsub!(/%\h\h/, Bundler::URI::TBLDECWWWCOMP_) + if EMAIL_REGEXP !~ addr + raise InvalidComponentError, + "an address in 'to' is invalid as uri-escaped addr-spec #{addr.dump}" + end + end + + true + end + private :check_to + + # Private setter for to +v+. + def set_to(v) + @to = v + end + protected :set_to + + # Setter for to +v+. + def to=(v) + check_to(v) + set_to(v) + v + end + + # Checks the headers +v+ component against either + # * HEADER_REGEXP + def check_headers(v) + return true unless v + return true if v.size == 0 + if HEADER_REGEXP !~ v + raise InvalidComponentError, + "bad component(expected opaque component): #{v}" + end + + true + end + private :check_headers + + # Private setter for headers +v+. + def set_headers(v) + @headers = [] + if v + v.split('&').each do |x| + @headers << x.split(/=/, 2) + end + end + end + protected :set_headers + + # Setter for headers +v+. + def headers=(v) + check_headers(v) + set_headers(v) + v + end + + # Constructs String from Bundler::URI. + def to_s + @scheme + ':' + + if @to + @to + else + '' + end + + if @headers.size > 0 + '?' + @headers.collect{|x| x.join('=')}.join('&') + else + '' + end + + if @fragment + '#' + @fragment + else + '' + end + end + + # Returns the RFC822 e-mail text equivalent of the URL, as a String. + # + # Example: + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("mailto:ruby-list@ruby-lang.org?Subject=subscribe&cc=myaddr") + # uri.to_mailtext + # # => "To: ruby-list@ruby-lang.org\nSubject: subscribe\nCc: myaddr\n\n\n" + # + def to_mailtext + to = Bundler::URI.decode_www_form_component(@to) + head = '' + body = '' + @headers.each do |x| + case x[0] + when 'body' + body = Bundler::URI.decode_www_form_component(x[1]) + when 'to' + to << ', ' + Bundler::URI.decode_www_form_component(x[1]) + else + head << Bundler::URI.decode_www_form_component(x[0]).capitalize + ': ' + + Bundler::URI.decode_www_form_component(x[1]) + "\n" + end + end + + "To: #{to} +#{head} +#{body} +" + end + alias to_rfc822text to_mailtext + end + + @@schemes['MAILTO'] = MailTo +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb new file mode 100644 index 0000000..e48e164 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb @@ -0,0 +1,533 @@ +# frozen_string_literal: false +#-- +# = uri/common.rb +# +# Author:: Akira Yamada +# License:: +# You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +module Bundler::URI + # + # Includes Bundler::URI::REGEXP::PATTERN + # + module RFC2396_REGEXP + # + # Patterns used to parse Bundler::URI's + # + module PATTERN + # :stopdoc: + + # RFC 2396 (Bundler::URI Generic Syntax) + # RFC 2732 (IPv6 Literal Addresses in URL's) + # RFC 2373 (IPv6 Addressing Architecture) + + # alpha = lowalpha | upalpha + ALPHA = "a-zA-Z" + # alphanum = alpha | digit + ALNUM = "#{ALPHA}\\d" + + # hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | + # "a" | "b" | "c" | "d" | "e" | "f" + HEX = "a-fA-F\\d" + # escaped = "%" hex hex + ESCAPED = "%[#{HEX}]{2}" + # mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | + # "(" | ")" + # unreserved = alphanum | mark + UNRESERVED = "\\-_.!~*'()#{ALNUM}" + # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | + # "$" | "," + # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | + # "$" | "," | "[" | "]" (RFC 2732) + RESERVED = ";/?:@&=+$,\\[\\]" + + # domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum + DOMLABEL = "(?:[#{ALNUM}](?:[-#{ALNUM}]*[#{ALNUM}])?)" + # toplabel = alpha | alpha *( alphanum | "-" ) alphanum + TOPLABEL = "(?:[#{ALPHA}](?:[-#{ALNUM}]*[#{ALNUM}])?)" + # hostname = *( domainlabel "." ) toplabel [ "." ] + HOSTNAME = "(?:#{DOMLABEL}\\.)*#{TOPLABEL}\\.?" + + # :startdoc: + end # PATTERN + + # :startdoc: + end # REGEXP + + # Class that parses String's into Bundler::URI's. + # + # It contains a Hash set of patterns and Regexp's that match and validate. + # + class RFC2396_Parser + include RFC2396_REGEXP + + # + # == Synopsis + # + # Bundler::URI::Parser.new([opts]) + # + # == Args + # + # The constructor accepts a hash as options for parser. + # Keys of options are pattern names of Bundler::URI components + # and values of options are pattern strings. + # The constructor generates set of regexps for parsing URIs. + # + # You can use the following keys: + # + # * :ESCAPED (Bundler::URI::PATTERN::ESCAPED in default) + # * :UNRESERVED (Bundler::URI::PATTERN::UNRESERVED in default) + # * :DOMLABEL (Bundler::URI::PATTERN::DOMLABEL in default) + # * :TOPLABEL (Bundler::URI::PATTERN::TOPLABEL in default) + # * :HOSTNAME (Bundler::URI::PATTERN::HOSTNAME in default) + # + # == Examples + # + # p = Bundler::URI::Parser.new(:ESCAPED => "(?:%[a-fA-F0-9]{2}|%u[a-fA-F0-9]{4})") + # u = p.parse("http://example.jp/%uABCD") #=> # + # Bundler::URI.parse(u.to_s) #=> raises Bundler::URI::InvalidURIError + # + # s = "http://example.com/ABCD" + # u1 = p.parse(s) #=> # + # u2 = Bundler::URI.parse(s) #=> # + # u1 == u2 #=> true + # u1.eql?(u2) #=> false + # + def initialize(opts = {}) + @pattern = initialize_pattern(opts) + @pattern.each_value(&:freeze) + @pattern.freeze + + @regexp = initialize_regexp(@pattern) + @regexp.each_value(&:freeze) + @regexp.freeze + end + + # The Hash of patterns. + # + # See also Bundler::URI::Parser.initialize_pattern. + attr_reader :pattern + + # The Hash of Regexp. + # + # See also Bundler::URI::Parser.initialize_regexp. + attr_reader :regexp + + # Returns a split Bundler::URI against regexp[:ABS_URI]. + def split(uri) + case uri + when '' + # null uri + + when @regexp[:ABS_URI] + scheme, opaque, userinfo, host, port, + registry, path, query, fragment = $~[1..-1] + + # Bundler::URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + + # absoluteURI = scheme ":" ( hier_part | opaque_part ) + # hier_part = ( net_path | abs_path ) [ "?" query ] + # opaque_part = uric_no_slash *uric + + # abs_path = "/" path_segments + # net_path = "//" authority [ abs_path ] + + # authority = server | reg_name + # server = [ [ userinfo "@" ] hostport ] + + if !scheme + raise InvalidURIError, + "bad Bundler::URI(absolute but no scheme): #{uri}" + end + if !opaque && (!path && (!host && !registry)) + raise InvalidURIError, + "bad Bundler::URI(absolute but no path): #{uri}" + end + + when @regexp[:REL_URI] + scheme = nil + opaque = nil + + userinfo, host, port, registry, + rel_segment, abs_path, query, fragment = $~[1..-1] + if rel_segment && abs_path + path = rel_segment + abs_path + elsif rel_segment + path = rel_segment + elsif abs_path + path = abs_path + end + + # Bundler::URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + + # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] + + # net_path = "//" authority [ abs_path ] + # abs_path = "/" path_segments + # rel_path = rel_segment [ abs_path ] + + # authority = server | reg_name + # server = [ [ userinfo "@" ] hostport ] + + else + raise InvalidURIError, "bad Bundler::URI(is not Bundler::URI?): #{uri}" + end + + path = '' if !path && !opaque # (see RFC2396 Section 5.2) + ret = [ + scheme, + userinfo, host, port, # X + registry, # X + path, # Y + opaque, # Y + query, + fragment + ] + return ret + end + + # + # == Args + # + # +uri+:: + # String + # + # == Description + # + # Parses +uri+ and constructs either matching Bundler::URI scheme object + # (File, FTP, HTTP, HTTPS, LDAP, LDAPS, or MailTo) or Bundler::URI::Generic. + # + # == Usage + # + # p = Bundler::URI::Parser.new + # p.parse("ldap://ldap.example.com/dc=example?user=john") + # #=> # + # + def parse(uri) + Bundler::URI.for(*self.split(uri), self) + end + + # + # == Args + # + # +uris+:: + # an Array of Strings + # + # == Description + # + # Attempts to parse and merge a set of URIs. + # + def join(*uris) + uris[0] = convert_to_uri(uris[0]) + uris.inject :merge + end + + # + # :call-seq: + # extract( str ) + # extract( str, schemes ) + # extract( str, schemes ) {|item| block } + # + # == Args + # + # +str+:: + # String to search + # +schemes+:: + # Patterns to apply to +str+ + # + # == Description + # + # Attempts to parse and merge a set of URIs. + # If no +block+ given, then returns the result, + # else it calls +block+ for each element in result. + # + # See also Bundler::URI::Parser.make_regexp. + # + def extract(str, schemes = nil) + if block_given? + str.scan(make_regexp(schemes)) { yield $& } + nil + else + result = [] + str.scan(make_regexp(schemes)) { result.push $& } + result + end + end + + # Returns Regexp that is default self.regexp[:ABS_URI_REF], + # unless +schemes+ is provided. Then it is a Regexp.union with self.pattern[:X_ABS_URI]. + def make_regexp(schemes = nil) + unless schemes + @regexp[:ABS_URI_REF] + else + /(?=#{Regexp.union(*schemes)}:)#{@pattern[:X_ABS_URI]}/x + end + end + + # + # :call-seq: + # escape( str ) + # escape( str, unsafe ) + # + # == Args + # + # +str+:: + # String to make safe + # +unsafe+:: + # Regexp to apply. Defaults to self.regexp[:UNSAFE] + # + # == Description + # + # Constructs a safe String from +str+, removing unsafe characters, + # replacing them with codes. + # + def escape(str, unsafe = @regexp[:UNSAFE]) + unless unsafe.kind_of?(Regexp) + # perhaps unsafe is String object + unsafe = Regexp.new("[#{Regexp.quote(unsafe)}]", false) + end + str.gsub(unsafe) do + us = $& + tmp = '' + us.each_byte do |uc| + tmp << sprintf('%%%02X', uc) + end + tmp + end.force_encoding(Encoding::US_ASCII) + end + + # + # :call-seq: + # unescape( str ) + # unescape( str, escaped ) + # + # == Args + # + # +str+:: + # String to remove escapes from + # +escaped+:: + # Regexp to apply. Defaults to self.regexp[:ESCAPED] + # + # == Description + # + # Removes escapes from +str+. + # + def unescape(str, escaped = @regexp[:ESCAPED]) + enc = str.encoding + enc = Encoding::UTF_8 if enc == Encoding::US_ASCII + str.gsub(escaped) { [$&[1, 2]].pack('H2').force_encoding(enc) } + end + + @@to_s = Kernel.instance_method(:to_s) + def inspect + @@to_s.bind_call(self) + end + + private + + # Constructs the default Hash of patterns. + def initialize_pattern(opts = {}) + ret = {} + ret[:ESCAPED] = escaped = (opts.delete(:ESCAPED) || PATTERN::ESCAPED) + ret[:UNRESERVED] = unreserved = opts.delete(:UNRESERVED) || PATTERN::UNRESERVED + ret[:RESERVED] = reserved = opts.delete(:RESERVED) || PATTERN::RESERVED + ret[:DOMLABEL] = opts.delete(:DOMLABEL) || PATTERN::DOMLABEL + ret[:TOPLABEL] = opts.delete(:TOPLABEL) || PATTERN::TOPLABEL + ret[:HOSTNAME] = hostname = opts.delete(:HOSTNAME) + + # RFC 2396 (Bundler::URI Generic Syntax) + # RFC 2732 (IPv6 Literal Addresses in URL's) + # RFC 2373 (IPv6 Addressing Architecture) + + # uric = reserved | unreserved | escaped + ret[:URIC] = uric = "(?:[#{unreserved}#{reserved}]|#{escaped})" + # uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" | + # "&" | "=" | "+" | "$" | "," + ret[:URIC_NO_SLASH] = uric_no_slash = "(?:[#{unreserved};?:@&=+$,]|#{escaped})" + # query = *uric + ret[:QUERY] = query = "#{uric}*" + # fragment = *uric + ret[:FRAGMENT] = fragment = "#{uric}*" + + # hostname = *( domainlabel "." ) toplabel [ "." ] + # reg-name = *( unreserved / pct-encoded / sub-delims ) # RFC3986 + unless hostname + ret[:HOSTNAME] = hostname = "(?:[a-zA-Z0-9\\-.]|%\\h\\h)+" + end + + # RFC 2373, APPENDIX B: + # IPv6address = hexpart [ ":" IPv4address ] + # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT + # hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ] + # hexseq = hex4 *( ":" hex4) + # hex4 = 1*4HEXDIG + # + # XXX: This definition has a flaw. "::" + IPv4address must be + # allowed too. Here is a replacement. + # + # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT + ret[:IPV4ADDR] = ipv4addr = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}" + # hex4 = 1*4HEXDIG + hex4 = "[#{PATTERN::HEX}]{1,4}" + # lastpart = hex4 | IPv4address + lastpart = "(?:#{hex4}|#{ipv4addr})" + # hexseq1 = *( hex4 ":" ) hex4 + hexseq1 = "(?:#{hex4}:)*#{hex4}" + # hexseq2 = *( hex4 ":" ) lastpart + hexseq2 = "(?:#{hex4}:)*#{lastpart}" + # IPv6address = hexseq2 | [ hexseq1 ] "::" [ hexseq2 ] + ret[:IPV6ADDR] = ipv6addr = "(?:#{hexseq2}|(?:#{hexseq1})?::(?:#{hexseq2})?)" + + # IPv6prefix = ( hexseq1 | [ hexseq1 ] "::" [ hexseq1 ] ) "/" 1*2DIGIT + # unused + + # ipv6reference = "[" IPv6address "]" (RFC 2732) + ret[:IPV6REF] = ipv6ref = "\\[#{ipv6addr}\\]" + + # host = hostname | IPv4address + # host = hostname | IPv4address | IPv6reference (RFC 2732) + ret[:HOST] = host = "(?:#{hostname}|#{ipv4addr}|#{ipv6ref})" + # port = *digit + ret[:PORT] = port = '\d*' + # hostport = host [ ":" port ] + ret[:HOSTPORT] = hostport = "#{host}(?::#{port})?" + + # userinfo = *( unreserved | escaped | + # ";" | ":" | "&" | "=" | "+" | "$" | "," ) + ret[:USERINFO] = userinfo = "(?:[#{unreserved};:&=+$,]|#{escaped})*" + + # pchar = unreserved | escaped | + # ":" | "@" | "&" | "=" | "+" | "$" | "," + pchar = "(?:[#{unreserved}:@&=+$,]|#{escaped})" + # param = *pchar + param = "#{pchar}*" + # segment = *pchar *( ";" param ) + segment = "#{pchar}*(?:;#{param})*" + # path_segments = segment *( "/" segment ) + ret[:PATH_SEGMENTS] = path_segments = "#{segment}(?:/#{segment})*" + + # server = [ [ userinfo "@" ] hostport ] + server = "(?:#{userinfo}@)?#{hostport}" + # reg_name = 1*( unreserved | escaped | "$" | "," | + # ";" | ":" | "@" | "&" | "=" | "+" ) + ret[:REG_NAME] = reg_name = "(?:[#{unreserved}$,;:@&=+]|#{escaped})+" + # authority = server | reg_name + authority = "(?:#{server}|#{reg_name})" + + # rel_segment = 1*( unreserved | escaped | + # ";" | "@" | "&" | "=" | "+" | "$" | "," ) + ret[:REL_SEGMENT] = rel_segment = "(?:[#{unreserved};@&=+$,]|#{escaped})+" + + # scheme = alpha *( alpha | digit | "+" | "-" | "." ) + ret[:SCHEME] = scheme = "[#{PATTERN::ALPHA}][\\-+.#{PATTERN::ALPHA}\\d]*" + + # abs_path = "/" path_segments + ret[:ABS_PATH] = abs_path = "/#{path_segments}" + # rel_path = rel_segment [ abs_path ] + ret[:REL_PATH] = rel_path = "#{rel_segment}(?:#{abs_path})?" + # net_path = "//" authority [ abs_path ] + ret[:NET_PATH] = net_path = "//#{authority}(?:#{abs_path})?" + + # hier_part = ( net_path | abs_path ) [ "?" query ] + ret[:HIER_PART] = hier_part = "(?:#{net_path}|#{abs_path})(?:\\?(?:#{query}))?" + # opaque_part = uric_no_slash *uric + ret[:OPAQUE_PART] = opaque_part = "#{uric_no_slash}#{uric}*" + + # absoluteURI = scheme ":" ( hier_part | opaque_part ) + ret[:ABS_URI] = abs_uri = "#{scheme}:(?:#{hier_part}|#{opaque_part})" + # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] + ret[:REL_URI] = rel_uri = "(?:#{net_path}|#{abs_path}|#{rel_path})(?:\\?#{query})?" + + # Bundler::URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + ret[:URI_REF] = "(?:#{abs_uri}|#{rel_uri})?(?:##{fragment})?" + + ret[:X_ABS_URI] = " + (#{scheme}): (?# 1: scheme) + (?: + (#{opaque_part}) (?# 2: opaque) + | + (?:(?: + //(?: + (?:(?:(#{userinfo})@)? (?# 3: userinfo) + (?:(#{host})(?::(\\d*))?))? (?# 4: host, 5: port) + | + (#{reg_name}) (?# 6: registry) + ) + | + (?!//)) (?# XXX: '//' is the mark for hostport) + (#{abs_path})? (?# 7: path) + )(?:\\?(#{query}))? (?# 8: query) + ) + (?:\\#(#{fragment}))? (?# 9: fragment) + " + + ret[:X_REL_URI] = " + (?: + (?: + // + (?: + (?:(#{userinfo})@)? (?# 1: userinfo) + (#{host})?(?::(\\d*))? (?# 2: host, 3: port) + | + (#{reg_name}) (?# 4: registry) + ) + ) + | + (#{rel_segment}) (?# 5: rel_segment) + )? + (#{abs_path})? (?# 6: abs_path) + (?:\\?(#{query}))? (?# 7: query) + (?:\\#(#{fragment}))? (?# 8: fragment) + " + + ret + end + + # Constructs the default Hash of Regexp's. + def initialize_regexp(pattern) + ret = {} + + # for Bundler::URI::split + ret[:ABS_URI] = Regexp.new('\A\s*' + pattern[:X_ABS_URI] + '\s*\z', Regexp::EXTENDED) + ret[:REL_URI] = Regexp.new('\A\s*' + pattern[:X_REL_URI] + '\s*\z', Regexp::EXTENDED) + + # for Bundler::URI::extract + ret[:URI_REF] = Regexp.new(pattern[:URI_REF]) + ret[:ABS_URI_REF] = Regexp.new(pattern[:X_ABS_URI], Regexp::EXTENDED) + ret[:REL_URI_REF] = Regexp.new(pattern[:X_REL_URI], Regexp::EXTENDED) + + # for Bundler::URI::escape/unescape + ret[:ESCAPED] = Regexp.new(pattern[:ESCAPED]) + ret[:UNSAFE] = Regexp.new("[^#{pattern[:UNRESERVED]}#{pattern[:RESERVED]}]") + + # for Generic#initialize + ret[:SCHEME] = Regexp.new("\\A#{pattern[:SCHEME]}\\z") + ret[:USERINFO] = Regexp.new("\\A#{pattern[:USERINFO]}\\z") + ret[:HOST] = Regexp.new("\\A#{pattern[:HOST]}\\z") + ret[:PORT] = Regexp.new("\\A#{pattern[:PORT]}\\z") + ret[:OPAQUE] = Regexp.new("\\A#{pattern[:OPAQUE_PART]}\\z") + ret[:REGISTRY] = Regexp.new("\\A#{pattern[:REG_NAME]}\\z") + ret[:ABS_PATH] = Regexp.new("\\A#{pattern[:ABS_PATH]}\\z") + ret[:REL_PATH] = Regexp.new("\\A#{pattern[:REL_PATH]}\\z") + ret[:QUERY] = Regexp.new("\\A#{pattern[:QUERY]}\\z") + ret[:FRAGMENT] = Regexp.new("\\A#{pattern[:FRAGMENT]}\\z") + + ret + end + + def convert_to_uri(uri) + if uri.is_a?(Bundler::URI::Generic) + uri + elsif uri = String.try_convert(uri) + parse(uri) + else + raise ArgumentError, + "bad argument (expected Bundler::URI object or Bundler::URI string)" + end + end + + end # class Parser +end # module Bundler::URI diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb new file mode 100644 index 0000000..2029cfd --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb @@ -0,0 +1,114 @@ +# frozen_string_literal: false +module Bundler::URI + class RFC3986_Parser # :nodoc: + # Bundler::URI defined in RFC3986 + # this regexp is modified not to host is not empty string + RFC3986_URI = /\A(?(?[A-Za-z][+\-.0-9A-Za-z]*):(?\/\/(?(?:(?(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?(?\[(?:(?(?:\h{1,4}:){6}(?\h{1,4}:\h{1,4}|(?(?[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g\.\g\.\g))|::(?:\h{1,4}:){5}\g|\h{1,4}?::(?:\h{1,4}:){4}\g|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g|(?(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])+))?(?::(?\d*))?)(?(?:\/(?(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?\/(?:(?(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g)*)?)|(?\g(?:\/\g)*)|(?))(?:\?(?[^#]*))?(?:\#(?(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/ + RFC3986_relative_ref = /\A(?(?\/\/(?(?:(?(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?(?\[(?(?:\h{1,4}:){6}(?\h{1,4}:\h{1,4}|(?(?[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g\.\g\.\g))|::(?:\h{1,4}:){5}\g|\h{1,4}?::(?:\h{1,4}:){4}\g|(?:(?:\h{1,4}:){,1}\h{1,4})?::(?:\h{1,4}:){3}\g|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?v\h+\.[!$&-.0-;=A-Z_a-z~]+)\])|\g|(?(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])+))?(?::(?\d*))?)(?(?:\/(?(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?\/(?:(?(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g)*)?)|(?(?(?:%\h\h|[!$&-.0-9;=@-Z_a-z~])+)(?:\/\g)*)|(?))(?:\?(?[^#]*))?(?:\#(?(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/ + attr_reader :regexp + + def initialize + @regexp = default_regexp.each_value(&:freeze).freeze + end + + def split(uri) #:nodoc: + begin + uri = uri.to_str + rescue NoMethodError + raise InvalidURIError, "bad Bundler::URI(is not Bundler::URI?): #{uri.inspect}" + end + uri.ascii_only? or + raise InvalidURIError, "Bundler::URI must be ascii only #{uri.dump}" + if m = RFC3986_URI.match(uri) + query = m["query".freeze] + scheme = m["scheme".freeze] + opaque = m["path-rootless".freeze] + if opaque + opaque << "?#{query}" if query + [ scheme, + nil, # userinfo + nil, # host + nil, # port + nil, # registry + nil, # path + opaque, + nil, # query + m["fragment".freeze] + ] + else # normal + [ scheme, + m["userinfo".freeze], + m["host".freeze], + m["port".freeze], + nil, # registry + (m["path-abempty".freeze] || + m["path-absolute".freeze] || + m["path-empty".freeze]), + nil, # opaque + query, + m["fragment".freeze] + ] + end + elsif m = RFC3986_relative_ref.match(uri) + [ nil, # scheme + m["userinfo".freeze], + m["host".freeze], + m["port".freeze], + nil, # registry, + (m["path-abempty".freeze] || + m["path-absolute".freeze] || + m["path-noscheme".freeze] || + m["path-empty".freeze]), + nil, # opaque + m["query".freeze], + m["fragment".freeze] + ] + else + raise InvalidURIError, "bad Bundler::URI(is not Bundler::URI?): #{uri.inspect}" + end + end + + def parse(uri) # :nodoc: + Bundler::URI.for(*self.split(uri), self) + end + + + def join(*uris) # :nodoc: + uris[0] = convert_to_uri(uris[0]) + uris.inject :merge + end + + @@to_s = Kernel.instance_method(:to_s) + def inspect + @@to_s.bind_call(self) + end + + private + + def default_regexp # :nodoc: + { + SCHEME: /\A[A-Za-z][A-Za-z0-9+\-.]*\z/, + USERINFO: /\A(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*\z/, + HOST: /\A(?:(?\[(?:(?(?:\h{1,4}:){6}(?\h{1,4}:\h{1,4}|(?(?[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g\.\g\.\g))|::(?:\h{1,4}:){5}\g|\h{,4}::(?:\h{1,4}:){4}\g|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g|(?(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])*))\z/, + ABS_PATH: /\A\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*(?:\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*)*\z/, + REL_PATH: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+(?:\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*)*\z/, + QUERY: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/, + FRAGMENT: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/, + OPAQUE: /\A(?:[^\/].*)?\z/, + PORT: /\A[\x09\x0a\x0c\x0d ]*\d*[\x09\x0a\x0c\x0d ]*\z/, + } + end + + def convert_to_uri(uri) + if uri.is_a?(Bundler::URI::Generic) + uri + elsif uri = String.try_convert(uri) + parse(uri) + else + raise ArgumentError, + "bad argument (expected Bundler::URI object or Bundler::URI string)" + end + end + + end # class Parser +end # module Bundler::URI diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/version.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/version.rb new file mode 100644 index 0000000..f2bb0eb --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/version.rb @@ -0,0 +1,6 @@ +module Bundler::URI + # :stopdoc: + VERSION_CODE = '001001'.freeze + VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze + # :startdoc: +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/ws.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/ws.rb new file mode 100644 index 0000000..58e08bf --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/ws.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: false +# = uri/ws.rb +# +# Author:: Matt Muller +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +require_relative 'generic' + +module Bundler::URI + + # + # The syntax of WS URIs is defined in RFC6455 section 3. + # + # Note that the Ruby Bundler::URI library allows WS URLs containing usernames and + # passwords. This is not legal as per the RFC, but used to be + # supported in Internet Explorer 5 and 6, before the MS04-004 security + # update. See . + # + class WS < Generic + # A Default port of 80 for Bundler::URI::WS. + DEFAULT_PORT = 80 + + # An Array of the available components for Bundler::URI::WS. + COMPONENT = %i[ + scheme + userinfo host port + path + query + ].freeze + + # + # == Description + # + # Creates a new Bundler::URI::WS object from components, with syntax checking. + # + # The components accepted are userinfo, host, port, path, and query. + # + # The components should be provided either as an Array, or as a Hash + # with keys formed by preceding the component names with a colon. + # + # If an Array is used, the components must be passed in the + # order [userinfo, host, port, path, query]. + # + # Example: + # + # uri = Bundler::URI::WS.build(host: 'www.example.com', path: '/foo/bar') + # + # uri = Bundler::URI::WS.build([nil, "www.example.com", nil, "/path", "query"]) + # + # Currently, if passed userinfo components this method generates + # invalid WS URIs as per RFC 1738. + # + def self.build(args) + tmp = Util.make_components_hash(self, args) + super(tmp) + end + + # + # == Description + # + # Returns the full path for a WS Bundler::URI, as required by Net::HTTP::Get. + # + # If the Bundler::URI contains a query, the full path is Bundler::URI#path + '?' + Bundler::URI#query. + # Otherwise, the path is simply Bundler::URI#path. + # + # Example: + # + # uri = Bundler::URI::WS.build(path: '/foo/bar', query: 'test=true') + # uri.request_uri # => "/foo/bar?test=true" + # + def request_uri + return unless @path + + url = @query ? "#@path?#@query" : @path.dup + url.start_with?(?/.freeze) ? url : ?/ + url + end + end + + @@schemes['WS'] = WS + +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/wss.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/wss.rb new file mode 100644 index 0000000..3827053 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendor/uri/lib/uri/wss.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: false +# = uri/wss.rb +# +# Author:: Matt Muller +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +require_relative 'ws' + +module Bundler::URI + + # The default port for WSS URIs is 443, and the scheme is 'wss:' rather + # than 'ws:'. Other than that, WSS URIs are identical to WS URIs; + # see Bundler::URI::WS. + class WSS < WS + # A Default port of 443 for Bundler::URI::WSS + DEFAULT_PORT = 443 + end + @@schemes['WSS'] = WSS +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendored_fileutils.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendored_fileutils.rb new file mode 100644 index 0000000..1be1138 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendored_fileutils.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +module Bundler; end +require_relative "vendor/fileutils/lib/fileutils" diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendored_molinillo.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendored_molinillo.rb new file mode 100644 index 0000000..d1976f5 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendored_molinillo.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +module Bundler; end +require_relative "vendor/molinillo/lib/molinillo" diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendored_persistent.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendored_persistent.rb new file mode 100644 index 0000000..dc9573e --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendored_persistent.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module Bundler + module Persistent + module Net + module HTTP + end + end + end +end +require_relative "vendor/net-http-persistent/lib/net/http/persistent" + +module Bundler + class PersistentHTTP < Persistent::Net::HTTP::Persistent + def connection_for(uri) + super(uri) do |connection| + result = yield connection + warn_old_tls_version_rubygems_connection(uri, connection) + result + end + end + + def warn_old_tls_version_rubygems_connection(uri, connection) + return unless connection.http.use_ssl? + return unless (uri.host || "").end_with?("rubygems.org") + + socket = connection.instance_variable_get(:@socket) + return unless socket + socket_io = socket.io + return unless socket_io.respond_to?(:ssl_version) + ssl_version = socket_io.ssl_version + + case ssl_version + when /TLSv([\d\.]+)/ + version = Gem::Version.new($1) + if version < Gem::Version.new("1.2") + Bundler.ui.warn \ + "Warning: Your Ruby version is compiled against a copy of OpenSSL that is very old. " \ + "Starting in January 2018, RubyGems.org will refuse connection requests from these " \ + "very old versions of OpenSSL. If you will need to continue installing gems after " \ + "January 2018, please follow this guide to upgrade: http://ruby.to/tls-outdated.", + :wrap => true + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendored_thor.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendored_thor.rb new file mode 100644 index 0000000..0666cfc --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendored_thor.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module Bundler + def self.require_thor_actions + require_relative "vendor/thor/lib/thor/actions" + end +end +require_relative "vendor/thor/lib/thor" diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendored_tmpdir.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendored_tmpdir.rb new file mode 100644 index 0000000..43b4fa7 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendored_tmpdir.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +module Bundler; end +require_relative "vendor/tmpdir/lib/tmpdir" diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendored_tsort.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendored_tsort.rb new file mode 100644 index 0000000..38aed0b --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendored_tsort.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +module Bundler; end +require_relative "vendor/tsort/lib/tsort" diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vendored_uri.rb b/games/FNaFB2/Ruby/stdlib/bundler/vendored_uri.rb new file mode 100644 index 0000000..905e815 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vendored_uri.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +module Bundler; end +require_relative "vendor/uri/lib/uri" diff --git a/games/FNaFB2/Ruby/stdlib/bundler/version.rb b/games/FNaFB2/Ruby/stdlib/bundler/version.rb new file mode 100644 index 0000000..4957902 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/version.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: false + +module Bundler + VERSION = "2.3.26".freeze + + def self.bundler_major_version + @bundler_major_version ||= VERSION.split(".").first.to_i + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/version_ranges.rb b/games/FNaFB2/Ruby/stdlib/bundler/version_ranges.rb new file mode 100644 index 0000000..12a956d --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/version_ranges.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +module Bundler + module VersionRanges + NEq = Struct.new(:version) + ReqR = Struct.new(:left, :right) + class ReqR + Endpoint = Struct.new(:version, :inclusive) do + def <=>(other) + if version.equal?(INFINITY) + return 0 if other.version.equal?(INFINITY) + return 1 + elsif other.version.equal?(INFINITY) + return -1 + end + + comp = version <=> other.version + return comp unless comp.zero? + + if inclusive && !other.inclusive + 1 + elsif !inclusive && other.inclusive + -1 + else + 0 + end + end + end + + def to_s + "#{left.inclusive ? "[" : "("}#{left.version}, #{right.version}#{right.inclusive ? "]" : ")"}" + end + INFINITY = begin + inf = Object.new + def inf.to_s + "∞" + end + def inf.<=>(other) + return 0 if other.equal?(self) + 1 + end + inf.freeze + end + ZERO = Gem::Version.new("0.a") + + def cover?(v) + return false if left.inclusive && left.version > v + return false if !left.inclusive && left.version >= v + + if right.version != INFINITY + return false if right.inclusive && right.version < v + return false if !right.inclusive && right.version <= v + end + + true + end + + def empty? + left.version == right.version && !(left.inclusive && right.inclusive) + end + + def single? + left.version == right.version + end + + def <=>(other) + return -1 if other.equal?(INFINITY) + + comp = left <=> other.left + return comp unless comp.zero? + + right <=> other.right + end + + UNIVERSAL = ReqR.new(ReqR::Endpoint.new(Gem::Version.new("0.a"), true), ReqR::Endpoint.new(ReqR::INFINITY, false)).freeze + end + + def self.for_many(requirements) + requirements = requirements.map(&:requirements).flatten(1).map {|r| r.join(" ") } + requirements << ">= 0.a" if requirements.empty? + requirement = Gem::Requirement.new(requirements) + self.for(requirement) + end + + def self.for(requirement) + ranges = requirement.requirements.map do |op, v| + case op + when "=" then ReqR.new(ReqR::Endpoint.new(v, true), ReqR::Endpoint.new(v, true)) + when "!=" then NEq.new(v) + when ">=" then ReqR.new(ReqR::Endpoint.new(v, true), ReqR::Endpoint.new(ReqR::INFINITY, false)) + when ">" then ReqR.new(ReqR::Endpoint.new(v, false), ReqR::Endpoint.new(ReqR::INFINITY, false)) + when "<" then ReqR.new(ReqR::Endpoint.new(ReqR::ZERO, true), ReqR::Endpoint.new(v, false)) + when "<=" then ReqR.new(ReqR::Endpoint.new(ReqR::ZERO, true), ReqR::Endpoint.new(v, true)) + when "~>" then ReqR.new(ReqR::Endpoint.new(v, true), ReqR::Endpoint.new(v.bump, false)) + else raise "unknown version op #{op} in requirement #{requirement}" + end + end.uniq + ranges, neqs = ranges.partition {|r| !r.is_a?(NEq) } + + [ranges.sort, neqs.map(&:version)] + end + + def self.empty?(ranges, neqs) + !ranges.reduce(ReqR::UNIVERSAL) do |last_range, curr_range| + next false unless last_range + next false if curr_range.single? && neqs.include?(curr_range.left.version) + next curr_range if last_range.right.version == ReqR::INFINITY + case last_range.right.version <=> curr_range.left.version + # higher + when 1 then next ReqR.new(curr_range.left, last_range.right) + # equal + when 0 + if last_range.right.inclusive && curr_range.left.inclusive && !neqs.include?(curr_range.left.version) + ReqR.new(curr_range.left, [curr_range.right, last_range.right].max) + end + # lower + when -1 then next false + end + end + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/vlad.rb b/games/FNaFB2/Ruby/stdlib/bundler/vlad.rb new file mode 100644 index 0000000..538e8c3 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/vlad.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative "shared_helpers" +Bundler::SharedHelpers.major_deprecation 2, + "The Bundler task for Vlad" + +# Vlad task for Bundler. +# +# Add "require 'bundler/vlad'" in your Vlad deploy.rb, and +# include the vlad:bundle:install task in your vlad:deploy task. +require_relative "deployment" + +include Rake::DSL if defined? Rake::DSL + +namespace :vlad do + Bundler::Deployment.define_task(Rake::RemoteTask, :remote_task, :roles => :app) +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/worker.rb b/games/FNaFB2/Ruby/stdlib/bundler/worker.rb new file mode 100644 index 0000000..5e4ee21 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/worker.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +module Bundler + class Worker + POISON = Object.new + + class WrappedException < StandardError + attr_reader :exception + def initialize(exn) + @exception = exn + end + end + + # @return [String] the name of the worker + attr_reader :name + + # Creates a worker pool of specified size + # + # @param size [Integer] Size of pool + # @param name [String] name the name of the worker + # @param func [Proc] job to run in inside the worker pool + def initialize(size, name, func) + @name = name + @request_queue = Thread::Queue.new + @response_queue = Thread::Queue.new + @func = func + @size = size + @threads = nil + @previous_interrupt_handler = nil + end + + # Enqueue a request to be executed in the worker pool + # + # @param obj [String] mostly it is name of spec that should be downloaded + def enq(obj) + create_threads unless @threads + @request_queue.enq obj + end + + # Retrieves results of job function being executed in worker pool + def deq + result = @response_queue.deq + raise result.exception if result.is_a?(WrappedException) + result + end + + def stop + stop_threads + end + + private + + def process_queue(i) + loop do + obj = @request_queue.deq + break if obj.equal? POISON + @response_queue.enq apply_func(obj, i) + end + end + + def apply_func(obj, i) + @func.call(obj, i) + rescue Exception => e # rubocop:disable Lint/RescueException + WrappedException.new(e) + end + + # Stop the worker threads by sending a poison object down the request queue + # so as worker threads after retrieving it, shut themselves down + def stop_threads + return unless @threads + + @threads.each { @request_queue.enq POISON } + @threads.each(&:join) + + remove_interrupt_handler + + @threads = nil + end + + def abort_threads + Bundler.ui.debug("\n#{caller.join("\n")}") + @threads.each(&:exit) + exit 1 + end + + def create_threads + creation_errors = [] + + @threads = Array.new(@size) do |i| + begin + Thread.start { process_queue(i) }.tap do |thread| + thread.name = "#{name} Worker ##{i}" if thread.respond_to?(:name=) + end + rescue ThreadError => e + creation_errors << e + nil + end + end.compact + + add_interrupt_handler unless @threads.empty? + + return if creation_errors.empty? + + message = "Failed to create threads for the #{name} worker: #{creation_errors.map(&:to_s).uniq.join(", ")}" + raise ThreadCreationError, message if @threads.empty? + Bundler.ui.info message + end + + def add_interrupt_handler + @previous_interrupt_handler = trap("INT") { abort_threads } + end + + def remove_interrupt_handler + return unless @previous_interrupt_handler + + trap "INT", @previous_interrupt_handler + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/bundler/yaml_serializer.rb b/games/FNaFB2/Ruby/stdlib/bundler/yaml_serializer.rb new file mode 100644 index 0000000..d5ecbd4 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/bundler/yaml_serializer.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +module Bundler + # A stub yaml serializer that can handle only hashes and strings (as of now). + module YAMLSerializer + module_function + + def dump(hash) + yaml = String.new("---") + yaml << dump_hash(hash) + end + + def dump_hash(hash) + yaml = String.new("\n") + hash.each do |k, v| + yaml << k << ":" + if v.is_a?(Hash) + yaml << dump_hash(v).gsub(/^(?!$)/, " ") # indent all non-empty lines + elsif v.is_a?(Array) # Expected to be array of strings + yaml << "\n- " << v.map {|s| s.to_s.gsub(/\s+/, " ").inspect }.join("\n- ") << "\n" + else + yaml << " " << v.to_s.gsub(/\s+/, " ").inspect << "\n" + end + end + yaml + end + + ARRAY_REGEX = / + ^ + (?:[ ]*-[ ]) # '- ' before array items + (['"]?) # optional opening quote + (.*) # value + \1 # matching closing quote + $ + /xo.freeze + + HASH_REGEX = / + ^ + ([ ]*) # indentations + (.+) # key + (?::(?=(?:\s|$))) # : (without the lookahead the #key includes this when : is present in value) + [ ]? + (['"]?) # optional opening quote + (.*) # value + \3 # matching closing quote + $ + /xo.freeze + + def load(str) + res = {} + stack = [res] + last_hash = nil + last_empty_key = nil + str.split(/\r?\n/).each do |line| + if match = HASH_REGEX.match(line) + indent, key, quote, val = match.captures + key = convert_to_backward_compatible_key(key) + depth = indent.scan(/ /).length + if quote.empty? && val.empty? + new_hash = {} + stack[depth][key] = new_hash + stack[depth + 1] = new_hash + last_empty_key = key + last_hash = stack[depth] + else + stack[depth][key] = val + end + elsif match = ARRAY_REGEX.match(line) + _, val = match.captures + last_hash[last_empty_key] = [] unless last_hash[last_empty_key].is_a?(Array) + + last_hash[last_empty_key].push(val) + end + end + res + end + + # for settings' keys + def convert_to_backward_compatible_key(key) + key = "#{key}/" if key =~ /https?:/i && key !~ %r{/\Z} + key = key.gsub(".", "__") if key.include?(".") + key + end + + class << self + private :dump_hash, :convert_to_backward_compatible_key + end + end +end diff --git a/games/FNaFB2/Ruby/stdlib/cgi.rb b/games/FNaFB2/Ruby/stdlib/cgi.rb new file mode 100644 index 0000000..dda5eb1 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/cgi.rb @@ -0,0 +1,297 @@ +# frozen_string_literal: true +# +# cgi.rb - cgi support library +# +# Copyright (C) 2000 Network Applied Communication Laboratory, Inc. +# +# Copyright (C) 2000 Information-technology Promotion Agency, Japan +# +# Author: Wakou Aoyama +# +# Documentation: Wakou Aoyama (RDoc'd and embellished by William Webber) +# + +# == Overview +# +# The Common Gateway Interface (CGI) is a simple protocol for passing an HTTP +# request from a web server to a standalone program, and returning the output +# to the web browser. Basically, a CGI program is called with the parameters +# of the request passed in either in the environment (GET) or via $stdin +# (POST), and everything it prints to $stdout is returned to the client. +# +# This file holds the CGI class. This class provides functionality for +# retrieving HTTP request parameters, managing cookies, and generating HTML +# output. +# +# The file CGI::Session provides session management functionality; see that +# class for more details. +# +# See http://www.w3.org/CGI/ for more information on the CGI protocol. +# +# == Introduction +# +# CGI is a large class, providing several categories of methods, many of which +# are mixed in from other modules. Some of the documentation is in this class, +# some in the modules CGI::QueryExtension and CGI::HtmlExtension. See +# CGI::Cookie for specific information on handling cookies, and cgi/session.rb +# (CGI::Session) for information on sessions. +# +# For queries, CGI provides methods to get at environmental variables, +# parameters, cookies, and multipart request data. For responses, CGI provides +# methods for writing output and generating HTML. +# +# Read on for more details. Examples are provided at the bottom. +# +# == Queries +# +# The CGI class dynamically mixes in parameter and cookie-parsing +# functionality, environmental variable access, and support for +# parsing multipart requests (including uploaded files) from the +# CGI::QueryExtension module. +# +# === Environmental Variables +# +# The standard CGI environmental variables are available as read-only +# attributes of a CGI object. The following is a list of these variables: +# +# +# AUTH_TYPE HTTP_HOST REMOTE_IDENT +# CONTENT_LENGTH HTTP_NEGOTIATE REMOTE_USER +# CONTENT_TYPE HTTP_PRAGMA REQUEST_METHOD +# GATEWAY_INTERFACE HTTP_REFERER SCRIPT_NAME +# HTTP_ACCEPT HTTP_USER_AGENT SERVER_NAME +# HTTP_ACCEPT_CHARSET PATH_INFO SERVER_PORT +# HTTP_ACCEPT_ENCODING PATH_TRANSLATED SERVER_PROTOCOL +# HTTP_ACCEPT_LANGUAGE QUERY_STRING SERVER_SOFTWARE +# HTTP_CACHE_CONTROL REMOTE_ADDR +# HTTP_FROM REMOTE_HOST +# +# +# For each of these variables, there is a corresponding attribute with the +# same name, except all lower case and without a preceding HTTP_. +# +content_length+ and +server_port+ are integers; the rest are strings. +# +# === Parameters +# +# The method #params() returns a hash of all parameters in the request as +# name/value-list pairs, where the value-list is an Array of one or more +# values. The CGI object itself also behaves as a hash of parameter names +# to values, but only returns a single value (as a String) for each +# parameter name. +# +# For instance, suppose the request contains the parameter +# "favourite_colours" with the multiple values "blue" and "green". The +# following behavior would occur: +# +# cgi.params["favourite_colours"] # => ["blue", "green"] +# cgi["favourite_colours"] # => "blue" +# +# If a parameter does not exist, the former method will return an empty +# array, the latter an empty string. The simplest way to test for existence +# of a parameter is by the #has_key? method. +# +# === Cookies +# +# HTTP Cookies are automatically parsed from the request. They are available +# from the #cookies() accessor, which returns a hash from cookie name to +# CGI::Cookie object. +# +# === Multipart requests +# +# If a request's method is POST and its content type is multipart/form-data, +# then it may contain uploaded files. These are stored by the QueryExtension +# module in the parameters of the request. The parameter name is the name +# attribute of the file input field, as usual. However, the value is not +# a string, but an IO object, either an IOString for small files, or a +# Tempfile for larger ones. This object also has the additional singleton +# methods: +# +# #local_path():: the path of the uploaded file on the local filesystem +# #original_filename():: the name of the file on the client computer +# #content_type():: the content type of the file +# +# == Responses +# +# The CGI class provides methods for sending header and content output to +# the HTTP client, and mixes in methods for programmatic HTML generation +# from CGI::HtmlExtension and CGI::TagMaker modules. The precise version of HTML +# to use for HTML generation is specified at object creation time. +# +# === Writing output +# +# The simplest way to send output to the HTTP client is using the #out() method. +# This takes the HTTP headers as a hash parameter, and the body content +# via a block. The headers can be generated as a string using the #http_header() +# method. The output stream can be written directly to using the #print() +# method. +# +# === Generating HTML +# +# Each HTML element has a corresponding method for generating that +# element as a String. The name of this method is the same as that +# of the element, all lowercase. The attributes of the element are +# passed in as a hash, and the body as a no-argument block that evaluates +# to a String. The HTML generation module knows which elements are +# always empty, and silently drops any passed-in body. It also knows +# which elements require matching closing tags and which don't. However, +# it does not know what attributes are legal for which elements. +# +# There are also some additional HTML generation methods mixed in from +# the CGI::HtmlExtension module. These include individual methods for the +# different types of form inputs, and methods for elements that commonly +# take particular attributes where the attributes can be directly specified +# as arguments, rather than via a hash. +# +# === Utility HTML escape and other methods like a function. +# +# There are some utility tool defined in cgi/util.rb . +# And when include, you can use utility methods like a function. +# +# == Examples of use +# +# === Get form values +# +# require "cgi" +# cgi = CGI.new +# value = cgi['field_name'] # <== value string for 'field_name' +# # if not 'field_name' included, then return "". +# fields = cgi.keys # <== array of field names +# +# # returns true if form has 'field_name' +# cgi.has_key?('field_name') +# cgi.has_key?('field_name') +# cgi.include?('field_name') +# +# CAUTION! cgi['field_name'] returned an Array with the old +# cgi.rb(included in Ruby 1.6) +# +# === Get form values as hash +# +# require "cgi" +# cgi = CGI.new +# params = cgi.params +# +# cgi.params is a hash. +# +# cgi.params['new_field_name'] = ["value"] # add new param +# cgi.params['field_name'] = ["new_value"] # change value +# cgi.params.delete('field_name') # delete param +# cgi.params.clear # delete all params +# +# +# === Save form values to file +# +# require "pstore" +# db = PStore.new("query.db") +# db.transaction do +# db["params"] = cgi.params +# end +# +# +# === Restore form values from file +# +# require "pstore" +# db = PStore.new("query.db") +# db.transaction do +# cgi.params = db["params"] +# end +# +# +# === Get multipart form values +# +# require "cgi" +# cgi = CGI.new +# value = cgi['field_name'] # <== value string for 'field_name' +# value.read # <== body of value +# value.local_path # <== path to local file of value +# value.original_filename # <== original filename of value +# value.content_type # <== content_type of value +# +# and value has StringIO or Tempfile class methods. +# +# === Get cookie values +# +# require "cgi" +# cgi = CGI.new +# values = cgi.cookies['name'] # <== array of 'name' +# # if not 'name' included, then return []. +# names = cgi.cookies.keys # <== array of cookie names +# +# and cgi.cookies is a hash. +# +# === Get cookie objects +# +# require "cgi" +# cgi = CGI.new +# for name, cookie in cgi.cookies +# cookie.expires = Time.now + 30 +# end +# cgi.out("cookie" => cgi.cookies) {"string"} +# +# cgi.cookies # { "name1" => cookie1, "name2" => cookie2, ... } +# +# require "cgi" +# cgi = CGI.new +# cgi.cookies['name'].expires = Time.now + 30 +# cgi.out("cookie" => cgi.cookies['name']) {"string"} +# +# === Print http header and html string to $DEFAULT_OUTPUT ($>) +# +# require "cgi" +# cgi = CGI.new("html4") # add HTML generation methods +# cgi.out do +# cgi.html do +# cgi.head do +# cgi.title { "TITLE" } +# end + +# cgi.body do +# cgi.form("ACTION" => "uri") do +# cgi.p do +# cgi.textarea("get_text") + +# cgi.br + +# cgi.submit +# end +# end + +# cgi.pre do +# CGI.escapeHTML( +# "params: #{cgi.params.inspect}\n" + +# "cookies: #{cgi.cookies.inspect}\n" + +# ENV.collect do |key, value| +# "#{key} --> #{value}\n" +# end.join("") +# ) +# end +# end +# end +# end +# +# # add HTML generation methods +# CGI.new("html3") # html3.2 +# CGI.new("html4") # html4.01 (Strict) +# CGI.new("html4Tr") # html4.01 Transitional +# CGI.new("html4Fr") # html4.01 Frameset +# CGI.new("html5") # html5 +# +# === Some utility methods +# +# require 'cgi/util' +# CGI.escapeHTML('Usage: foo "bar" ') +# +# +# === Some utility methods like a function +# +# require 'cgi/util' +# include CGI::Util +# escapeHTML('Usage: foo "bar" ') +# h('Usage: foo "bar" ') # alias +# +# + +class CGI + VERSION = "0.3.5" +end + +require 'cgi/core' +require 'cgi/cookie' +require 'cgi/util' +CGI.autoload(:HtmlExtension, 'cgi/html') diff --git a/games/FNaFB2/Ruby/stdlib/cgi/cookie.rb b/games/FNaFB2/Ruby/stdlib/cgi/cookie.rb new file mode 100644 index 0000000..1a9c1a8 --- /dev/null +++ b/games/FNaFB2/Ruby/stdlib/cgi/cookie.rb @@ -0,0 +1,209 @@ +# frozen_string_literal: true +require_relative 'util' +class CGI + # Class representing an HTTP cookie. + # + # In addition to its specific fields and methods, a Cookie instance + # is a delegator to the array of its values. + # + # See RFC 2965. + # + # == Examples of use + # cookie1 = CGI::Cookie.new("name", "value1", "value2", ...) + # cookie1 = CGI::Cookie.new("name" => "name", "value" => "value") + # cookie1 = CGI::Cookie.new('name' => 'name', + # 'value' => ['value1', 'value2', ...], + # 'path' => 'path', # optional + # 'domain' => 'domain', # optional + # 'expires' => Time.now, # optional + # 'secure' => true, # optional + # 'httponly' => true # optional + # ) + # + # cgi.out("cookie" => [cookie1, cookie2]) { "string" } + # + # name = cookie1.name + # values = cookie1.value + # path = cookie1.path + # domain = cookie1.domain + # expires = cookie1.expires + # secure = cookie1.secure + # httponly = cookie1.httponly + # + # cookie1.name = 'name' + # cookie1.value = ['value1', 'value2', ...] + # cookie1.path = 'path' + # cookie1.domain = 'domain' + # cookie1.expires = Time.now + 30 + # cookie1.secure = true + # cookie1.httponly = true + class Cookie < Array + @@accept_charset="UTF-8" unless defined?(@@accept_charset) + + TOKEN_RE = %r"\A[[!-~]&&[^()<>@,;:\\\"/?=\[\]{}]]+\z" + PATH_VALUE_RE = %r"\A[[ -~]&&[^;]]*\z" + DOMAIN_VALUE_RE = %r"\A(?