· 4 years ago · May 31, 2021, 09:16 PM
1--[[
2 ComputerCraft Package Tool Installer
3 Author: PentagonLP
4 Version: 1.0
5 Lines of Code: 161; Characters: 5541
6]]
7
8-- Read arguments
9args = {...}
10
11-- FILE MANIPULATION FUNCTIONS --
12--[[ Checks if file exists
13 @param String filepath: Filepath to check
14 @return boolean: Does the file exist?
15--]]
16function file_exists(filepath)
17 local f=io.open(filepath,"r")
18 if f~=nil then
19 io.close(f)
20 return true
21 else
22 return false
23 end
24end
25
26--[[ Stores a file in a desired location
27 @param String filepath: Filepath where to create file (if file already exists, it gets overwritten)
28 @param String content: Content to store in file
29--]]
30function storeFile(filepath,content)
31 writefile = fs.open(filepath,"w")
32 writefile.write(content)
33 writefile.close()
34end
35
36--[[ Reads a file from a desired location
37 @param String filepath: Filepath to the file to read
38 @param String createnew: (Optional) Content to store in new file and return if file does not exist. Can be nil.
39 @return String|boolean content|error: Content of the file; If createnew is nil and file doesn't exist boolean false is returned
40--]]
41function readFile(filepath,createnew)
42 readfile = fs.open(filepath,"r")
43 if readfile == nil then
44 if not (createnew==nil) then
45 storeFile(filepath,createnew)
46 return createnew
47 else
48 return false
49 end
50 end
51 content = readfile.readAll()
52 readfile.close()
53 return content
54end
55
56--[[ Stores a table in a file
57 @param String filepath: Filepath where to create file (if file already exists, it gets overwritten)
58 @param Table data: Table to store in file
59--]]
60function storeData(filepath,data)
61 storeFile(filepath,textutils.serialize(data):gsub("\n",""))
62end
63
64--[[ Reads a table from a file in a desired location
65 @param String filepath: Filepath to the file to read
66 @param boolean createnew: If true, an empty table is stored in new file and returned if file does not exist.
67 @return Table|boolean content|error: Table thats stored in the file; If createnew is false and file doesn't exist boolean false is returned
68--]]
69function readData(filepath,createnew)
70 if createnew then
71 return textutils.unserialize(readFile(filepath,textutils.serialize({}):gsub("\n","")))
72 else
73 return textutils.unserialize(readFile(filepath,nil))
74 end
75end
76
77-- HTTP FETCH FUNCTIONS --
78--[[ Gets result of HTTP URL
79 @param String url: The desired URL
80 @return Table|boolean result|error: The result of the request; If the URL is not reachable, an error is printed in the terminal and boolean false is returned
81--]]
82function gethttpresult(url)
83 if not http.checkURL(url) then
84 print("ERROR: Url '" .. url .. "' is blocked in config. Unable to fetch data.")
85 return false
86 end
87 result = http.get(url)
88 if result == nil then
89 print("ERROR: Unable to reach '" .. url .. "'")
90 return false
91 end
92 return result
93end
94
95--[[ Download file HTTP URL
96 @param String filepath: Filepath where to create file (if file already exists, it gets overwritten)
97 @param String url: The desired URL
98 @return nil|boolean nil|error: nil; If the URL is not reachable, an error is printed in the terminal and boolean false is returned
99--]]
100function downloadfile(filepath,url)
101 result = gethttpresult(url)
102 if result == false then
103 return false
104 end
105 storeFile(filepath,result.readAll())
106end
107
108-- MISC HELPER FUNCTIONS --
109--[[ Checks wether a String starts with another one
110 @param String haystack: String to check wether is starts with another one
111 @param String needle: String to check wether another one starts with it
112 @return boolean result: Wether the firest String starts with the second one
113]]--
114function startsWith(haystack,needle)
115 return string.sub(haystack,1,string.len(needle))==needle
116end
117
118-- MAIN PROGRAMM --
119if (args[1]=="install") or (args[1]==nil) then
120 print("[Installer] Well, hello there!")
121 print("[Installer] Thank you for downloading the ComputerCraft Package Tool! Installing...")
122 print("[Installer] Installing 'properprint' library...")
123 if downloadfile("lib/properprint","https://raw.githubusercontent.com/PentagonLP/properprint/main/properprint")== false then
124 return false
125 end
126 print("[Installer] Successfully installed 'properprint'!")
127 print("[Installer] Installing 'ccpt'...")
128 if downloadfile("ccpt","https://raw.githubusercontent.com/PentagonLP/ccpt/main/ccpt")==false then
129 return false
130 end
131 print("[Installer] Successfully installed 'ccpt'!")
132 print("[Installer] Running 'ccpt update'...")
133 shell.run("ccpt","update")
134 print("[Installer] Reading package data...")
135 packagedata = readData("/.ccpt/packagedata")
136 print("[Installer] Storing installed packages...")
137 storeData("/.ccpt/installedpackages",{
138 ccpt = packagedata["ccpt"]["newestversion"],
139 pprint = packagedata["pprint"]["newestversion"]
140 })
141 print("[Installer] 'ccpt' successfully installed!")
142elseif args[1]=="update" then
143 print("[Installer] Updating 'ccpt'...")
144 if downloadfile("ccpt","https://raw.githubusercontent.com/PentagonLP/ccpt/main/ccpt")==false then
145 return false
146 end
147elseif args[1]=="remove" then
148 print("[Installer] Uninstalling 'ccpt'...")
149 fs.delete("/ccpt")
150 fs.delete("/.ccpt")
151 shell.setCompletionFunction("ccpt", nil)
152 if file_exists("startup") and startsWith(startup,"-- ccpt: Seach for updates\nshell.run(\"ccpt\",\"startup\")") then
153 print("[Installer] Removing 'ccpt' from startup...")
154 startup = readFile("startup","")
155 storeFile("startup",string.sub(startup,56))
156 end
157 print("[Installer] So long, and thanks for all the fish!")
158else
159 print("[Installer] Invalid argument: " .. args[1])
160end