diff --git a/luacheck-dev-1.rockspec b/luacheck-dev-1.rockspec index cc549540..0389dd14 100644 --- a/luacheck-dev-1.rockspec +++ b/luacheck-dev-1.rockspec @@ -45,6 +45,7 @@ build = { luacheck = "src/luacheck/init.lua", ["luacheck.builtin_standards"] = "src/luacheck/builtin_standards/init.lua", ["luacheck.builtin_standards.love"] = "src/luacheck/builtin_standards/love.lua", + ["luacheck.builtin_standards.minetest"] = "src/luacheck/builtin_standards/minetest.lua", ["luacheck.builtin_standards.playdate"] = "src/luacheck/builtin_standards/playdate.lua", ["luacheck.builtin_standards.ngx"] = "src/luacheck/builtin_standards/ngx.lua", ["luacheck.cache"] = "src/luacheck/cache.lua", diff --git a/spec/cli_spec.lua b/spec/cli_spec.lua index 40879e58..4ebb90aa 100644 --- a/spec/cli_spec.lua +++ b/spec/cli_spec.lua @@ -1023,7 +1023,7 @@ spec/samples/python_code.lua:1:6: (E011) expected '=' near '__future__' end) it("expands folders", function() - assert.matches("^Total: %d+ warnings / %d+ errors in 27 files\n$", get_output "spec/samples -qqq --no-config --exclude-files spec/samples/global_fields.lua") + assert.matches("^Total: %d+ warnings / %d+ errors in 28 files\n$", get_output "spec/samples -qqq --no-config --exclude-files spec/samples/global_fields.lua") end) it("uses --include-files when expanding folders", function() @@ -1242,6 +1242,7 @@ Checking spec/samples/globals.lua 2 warnings Checking spec/samples/indirect_globals.lua 3 warnings Checking spec/samples/inline_options.lua 7 warnings / 2 errors Checking spec/samples/line_length.lua 8 warnings +Checking spec/samples/minetest.lua 2 warnings Checking spec/samples/python_code.lua 1 error Checking spec/samples/read_globals.lua 5 warnings Checking spec/samples/read_globals_inline_options.lua 3 warnings @@ -1252,7 +1253,7 @@ Checking spec/samples/unused_secondaries.lua 4 warnings Checking spec/samples/utf8.lua 4 warnings Checking spec/samples/utf8_error.lua 1 error -Total: 73 warnings / 9 errors in 20 files +Total: 75 warnings / 9 errors in 21 files ]]):gsub("(spec/samples)/", "%1"..package.config:sub(1, 1)), get_output "spec/samples --config=spec/configs/exclude_files_config.luacheckrc -qq --exclude-files spec/samples/global_fields.lua") end) @@ -1268,6 +1269,7 @@ Checking globals.lua 2 warnings Checking indirect_globals.lua 3 warnings Checking inline_options.lua 7 warnings / 2 errors Checking line_length.lua 8 warnings +Checking minetest.lua 2 warnings Checking python_code.lua 1 error Checking read_globals.lua 5 warnings Checking read_globals_inline_options.lua 3 warnings @@ -1278,7 +1280,7 @@ Checking unused_secondaries.lua 4 warnings Checking utf8.lua 4 warnings Checking utf8_error.lua 1 error -Total: 73 warnings / 9 errors in 20 files +Total: 75 warnings / 9 errors in 21 files ]], get_output(". --config=spec/configs/exclude_files_config.luacheckrc -qq --exclude-files global_fields.lua", "spec/samples/")) end) @@ -1293,6 +1295,7 @@ Checking globals.lua 2 warnings Checking indirect_globals.lua 3 warnings Checking inline_options.lua 7 warnings / 2 errors Checking line_length.lua 8 warnings +Checking minetest.lua 2 warnings Checking python_code.lua 1 error Checking redefined.lua 7 warnings Checking reversed_fornum.lua 1 warning @@ -1301,7 +1304,7 @@ Checking unused_secondaries.lua 4 warnings Checking utf8.lua 4 warnings Checking utf8_error.lua 1 error -Total: 65 warnings / 9 errors in 18 files +Total: 67 warnings / 9 errors in 19 files ]], get_output(". --config=spec/configs/exclude_files_config.luacheckrc -qq --exclude-files global_fields.lua --exclude-files " .. quote("./read*"), "spec/samples/")) end) @@ -1351,6 +1354,17 @@ Total: 1 warning / 0 errors in 1 file ]], get_output "spec/samples/globals.lua --config=spec/configs/import_config.luacheckrc") end) + describe("responds to builtin std preset", function() + it("minetest", function() + -- make sure minetest sample has something that normally throws a lint error + assert.equal(1, get_exitcode "spec/samples/minetest.lua --no-config") + -- turning on minetest std should pass all lints + assert.equal(0, get_exitcode "spec/samples/minetest.lua --no-config --std minetest") + -- confirm minetest std set isn't just blindly allowing anything + assert.equal(1, get_exitcode "spec/samples/sample.rockspec --no-config --std minetest") + end) + end) + describe("global path", function() setup(function() os.rename(".luacheckrc", ".luacheckrc.bak") diff --git a/spec/samples/minetest.lua b/spec/samples/minetest.lua new file mode 100644 index 00000000..b7206937 --- /dev/null +++ b/spec/samples/minetest.lua @@ -0,0 +1,2 @@ +local _ = minetest +local _ = minetest.get_current_modname() diff --git a/src/luacheck/builtin_standards/init.lua b/src/luacheck/builtin_standards/init.lua index f35c2d75..097fee2d 100644 --- a/src/luacheck/builtin_standards/init.lua +++ b/src/luacheck/builtin_standards/init.lua @@ -1,4 +1,5 @@ local love = require "luacheck.builtin_standards.love" +local minetest = require "luacheck.builtin_standards.minetest" local playdate = require "luacheck.builtin_standards.playdate" local ngx = require "luacheck.builtin_standards.ngx" local standards = require "luacheck.standards" @@ -296,6 +297,8 @@ builtin_standards.busted = { builtin_standards.love = love +builtin_standards.minetest = minetest + builtin_standards.playdate = playdate builtin_standards.rockspec = { diff --git a/src/luacheck/builtin_standards/minetest.lua b/src/luacheck/builtin_standards/minetest.lua new file mode 100644 index 00000000..ef06a42c --- /dev/null +++ b/src/luacheck/builtin_standards/minetest.lua @@ -0,0 +1,479 @@ +-- minetest lua api standard +-- lua-api reference: https://github.com/minetest/minetest/blob/master/doc/lua_api.md +local standards = require "luacheck.standards" + +local empty = {} +local read_write = {read_only = false} +local open_table = {read_only = false, other_fields = true} + +-- main namespace +local minetest = { + fields = { + -- Utilities + get_current_modname = empty, + get_modpath = empty, + get_modnames = empty, + get_game_info = empty, + get_worldpath = empty, + is_singleplayer = empty, + features = open_table, + has_feature = empty, + get_player_information = empty, + get_player_window_information = empty, + mkdir = empty, + rmdir = empty, + cpdir = empty, + mvdir = empty, + get_dir_list = empty, + safe_file_write = empty, + get_version = empty, + sha1 = empty, + colorspec_to_colorstring = empty, + colorspec_to_bytes = empty, + encode_png = empty, + urlencode = empty, + + -- Logging + debug = empty, + log = empty, + + -- Environment + register_node = empty, + register_craftitem = empty, + register_tool = empty, + override_item = empty, + unregister_item = empty, + register_entity = empty, + register_abm = empty, + register_lbm = empty, + register_alias = empty, + register_alias_force = empty, + register_ore = empty, + register_biome = empty, + unregister_biome = empty, + register_decoration = empty, + register_schematic = empty, + clear_registered_biomes = empty, + clear_registered_decorations = empty, + clear_registered_ores = empty, + clear_registered_schematics = empty, + + -- Gameplay + register_craft = empty, + clear_craft = empty, + register_chatcommand = empty, + override_chatcommand = empty, + unregister_chatcommand = empty, + register_privilege = empty, + register_authentication_handler = empty, + + -- Global callback registration functions + register_globalstep = empty, + register_on_mods_loaded = empty, + register_on_shutdown = empty, + register_on_placenode = empty, + register_on_dignode = empty, + register_on_punchnode = empty, + register_on_generated = empty, + register_on_newplayer = empty, + register_on_punchplayer = empty, + register_on_rightclickplayer = empty, + register_on_player_hpchange = empty, + register_on_dieplayer = empty, + register_on_respawnplayer = empty, + register_on_prejoinplayer = empty, + register_on_joinplayer = empty, + register_on_leaveplayer = empty, + register_on_authplayer = empty, + register_on_auth_fail = empty, + register_on_cheat = empty, + register_on_chat_message = empty, + register_on_chatcommand = empty, + register_on_player_receive_fields = empty, + register_on_craft = empty, + register_craft_predict = empty, + register_allow_player_inventory_action = empty, + register_on_player_inventory_action = empty, + register_on_protection_violation = empty, + register_on_item_eat = empty, + register_on_item_pickup = empty, + register_on_priv_grant = empty, + register_on_priv_revoke = empty, + register_can_bypass_userlimit = empty, + register_on_modchannel_message = empty, + register_on_liquid_transformed = empty, + register_on_mapblocks_changed = empty, + -- ... and corresponding callback tables + registered_on_chat_messages = open_table, + registered_on_chatcommands = open_table, + registered_globalsteps = open_table, + registered_on_mods_loaded = open_table, + registered_on_shutdown = open_table, + registered_on_punchnodes = open_table, + registered_on_placenodes = open_table, + registered_on_dignodes = open_table, + registered_on_generateds = open_table, + registered_on_newplayers = open_table, + registered_on_dieplayers = open_table, + registered_on_respawnplayers = open_table, + registered_on_prejoinplayers = open_table, + registered_on_joinplayers = open_table, + registered_on_leaveplayers = open_table, + registered_on_player_receive_fields = open_table, + registered_on_cheats = open_table, + registered_on_crafts = open_table, + registered_craft_predicts = open_table, + registered_on_protection_violation = open_table, + registered_on_item_eats = open_table, + registered_on_item_pickups = open_table, + registered_on_punchplayers = open_table, + registered_on_priv_grant = open_table, + registered_on_priv_revoke = open_table, + registered_on_authplayers = open_table, + registered_can_bypass_userlimit = open_table, + registered_on_modchannel_message = open_table, + registered_on_player_inventory_actions = open_table, + registered_allow_player_inventory_actions = open_table, + registered_on_rightclickplayers = open_table, + registered_on_liquid_transformed = open_table, + registered_on_mapblocks_changed = open_table, + + -- Setting-related + settings = standards.def_fields("get", "get_bool", "get_np_group", "get_flags", "set", "set_bool", + "set_np_group", "remove", "get_names", "has", "write", "to_table"), + setting_get_pos = empty, + + -- Authentication + string_to_privs = empty, + privs_to_string = empty, + get_player_privs = empty, + check_player_privs = empty, + check_password_entry = empty, + get_password_hash = empty, + get_player_ip = empty, + get_auth_handler = empty, + notify_authentication_modified = empty, + set_player_password = empty, + set_player_privs = empty, + change_player_privs = empty, + auth_reload = empty, + + -- Chat + chat_send_all = empty, + chat_send_player = empty, + format_chat_message = empty, + + -- Environment access + set_node = empty, + add_node = empty, + bulk_set_node = empty, + swap_node = empty, + remove_node = empty, + get_node = empty, + get_node_or_nil = empty, + get_node_light = empty, + get_natural_light = empty, + get_artificial_light = empty, + place_node = empty, + dig_node = empty, + punch_node = empty, + spawn_falling_node = empty, + find_nodes_with_meta = empty, + get_meta = empty, + get_node_timer = empty, + add_entity = empty, + add_item = empty, + get_player_by_name = empty, + get_objects_inside_radius = empty, + get_objects_in_area = empty, + set_timeofday = empty, + get_timeofday = empty, + get_gametime = empty, + get_day_count = empty, + find_node_near = empty, + find_nodes_in_area = empty, + find_nodes_in_area_under_air = empty, + get_perlin = empty, + get_voxel_manip = empty, + set_gen_notify = empty, + get_gen_notify = empty, + get_decoration_id = empty, + get_mapgen_object = empty, + get_heat = empty, + get_humidity = empty, + get_biome_data = empty, + get_biome_id = empty, + get_biome_name = empty, + get_mapgen_params = empty, + set_mapgen_params = empty, + get_mapgen_edges = empty, + get_mapgen_setting = empty, + get_mapgen_setting_noiseparams = empty, + set_mapgen_setting = empty, + set_mapgen_setting_noiseparams = empty, + set_noiseparams = empty, + get_noiseparams = empty, + generate_ores = empty, + generate_decorations = empty, + clear_objects = empty, + load_area = empty, + emerge_area = empty, + delete_area = empty, + line_of_sight = empty, + raycast = empty, + find_path = empty, + spawn_tree = empty, + transforming_liquid_add = empty, + get_node_max_level = empty, + get_node_level = empty, + set_node_level = empty, + add_node_level = empty, + get_node_boxes = empty, + fix_light = empty, + check_single_for_falling = empty, + check_for_falling = empty, + get_spawn_level = empty, + + -- Mod channels + mod_channel_join = empty, + + -- Inventory + get_inventory = empty, + create_detached_inventory = empty, + remove_detached_inventory = empty, + do_item_eat = empty, + + -- Formspec + show_formspec = empty, + close_formspec = empty, + formspec_escape = empty, + explode_table_event = empty, + explode_textlist_event = empty, + explode_scrollbar_event = empty, + + -- Item handling + inventorycube = empty, + get_pointed_thing_position = empty, + dir_to_facedir = empty, + facedir_to_dir = empty, + dir_to_fourdir = empty, + fourdir_to_dir = empty, + dir_to_wallmounted = empty, + wallmounted_to_dir = empty, + dir_to_yaw = empty, + yaw_to_dir = empty, + is_colored_paramtype = empty, + strip_param2_color = empty, + get_node_drops = empty, + get_craft_result = empty, + get_craft_recipe = empty, + get_all_craft_recipes = empty, + handle_node_drops = empty, + itemstring_with_palette = empty, + itemstring_with_color = empty, + + -- Rollback + rollback_get_node_actions = empty, + rollback_revert_actions_by = empty, + + -- Defaults for the on_place and on_drop item definition functions + item_place_node = empty, + item_place_object = empty, + item_place = empty, + item_pickup = empty, + item_drop = empty, + item_eat = empty, + + -- Defaults for the on_punch and on_dig node definition callbacks + node_punch = empty, + node_dig = empty, + + -- Sounds + sound_play = empty, + sound_stop = empty, + sound_fade = empty, + + -- Timing + after = empty, + + -- Async environment + handle_async = empty, + register_async_dofile = empty, + + -- Server + request_shutdown = empty, + cancel_shutdown_requests = empty, + get_server_status = empty, + get_server_uptime = empty, + get_server_max_lag = empty, + remove_player = empty, + remove_player_auth = empty, + dynamic_add_media = empty, + + -- Bans + get_ban_list = empty, + get_ban_description = empty, + ban_player = empty, + unban_player_or_ip = empty, + kick_player = empty, + disconnect_player = empty, + + -- Particles + add_particle = empty, + add_particlespawner = empty, + delete_particlespawner = empty, + + -- Schematics + create_schematic = empty, + place_schematic = empty, + place_schematic_on_vmanip = empty, + serialize_schematic = empty, + read_schematic = empty, + + -- HTTP Requests + request_http_api = empty, + + -- Storage API + get_mod_storage = empty, + + -- Misc + get_connected_players = empty, + is_player = empty, + player_exists = empty, + hud_replace_builtin = empty, + parse_relative_number = empty, + send_join_message = empty, + send_leave_message = empty, + hash_node_position = empty, + get_position_from_hash = empty, + get_item_group = empty, + get_node_group = empty, + raillike_group = empty, + get_content_id = empty, + get_name_from_content_id = empty, + parse_json = empty, + write_json = empty, + serialize = empty, + deserialize = empty, + compress = empty, + decompress = empty, + rgba = empty, + encode_base64 = empty, + decode_base64 = empty, + is_protected = read_write, + record_protection_violation = empty, + is_creative_enabled = empty, + is_area_protected = empty, + rotate_and_place = empty, + rotate_node = empty, + calculate_knockback = empty, + forceload_block = empty, + forceload_free_block = empty, + compare_block_status = empty, + request_insecure_environment = empty, + global_exists = empty, + + -- Error Handling + error_handler = read_write, + + -- Helper functions + wrap_text = empty, + pos_to_string = empty, + string_to_pos = empty, + string_to_area = empty, + is_yes = empty, + is_nan = empty, + get_us_time = empty, + pointed_thing_to_face_pos = empty, + get_tool_wear_after_use = empty, + get_dig_params = empty, + get_hit_params = empty, + colorize = empty, + + -- Translations + get_translator = empty, + get_translated_string = empty, + translate = empty, + + -- Global tables + registered_items = open_table, + registered_nodes = open_table, + registered_craftitems = open_table, + registered_tools = open_table, + registered_entities = open_table, + object_refs = open_table, + luaentities = open_table, + registered_abms = open_table, + registered_lbms = open_table, + registered_aliases = open_table, + registered_ores = open_table, + registered_biomes = open_table, + registered_decorations = open_table, + registered_schematics = open_table, + registered_chatcommands = open_table, + registered_privileges = open_table, + + -- Constants (see: https://github.com/minetest/minetest/blob/master/builtin/game/constants.lua) + CONTENT_UNKNOWN = empty, + CONTENT_AIR = empty, + CONTENT_IGNORE = empty, + EMERGE_CANCELLED = empty, + EMERGE_ERRORED = empty, + EMERGE_FROM_MEMORY = empty, + EMERGE_FROM_DISK = empty, + EMERGE_GENERATED = empty, + MAP_BLOCKSIZE = empty, + PLAYER_MAX_HP_DEFAULT = empty, + PLAYER_MAX_BREATH_DEFAULT = empty, + LIGHT_MAX = empty + } +} + +-- Table additions +local table = standards.def_fields("copy", "indexof", "insert_all", "key_value_swap", "shuffle") + +-- String additions +local string = standards.def_fields("split", "trim") + +-- Math additions +local math = standards.def_fields("hypot", "sign", "factorial", "round") + +-- Bit library +local bit = standards.def_fields("tobit","tohex","bnot","band","bor","bxor","lshift","rshift","arshift","rol","ror", + "bswap") + +-- vector util +local vector = standards.def_fields("new", "zero", "copy", "from_string", "to_string", "direction", "distance", + "length", "normalize", "floor", "round", "apply", "combine", "equals", "sort", "angle", "dot", "cross", "offset", + "check", "in_area", "add", "subtract", "multiply", "divide", "rotate", "rotate_around_axis", "dir_to_rotation") + +return { + read_globals = { + -- main namespace + minetest = minetest, + + -- extensions + table = table, + math = math, + bit = bit, + string = string, + + -- Helper functions + vector = vector, + dump = empty, + dump2 = empty, + + -- classes + AreaStore = empty, + ItemStack = empty, + PerlinNoise = empty, + PerlinNoiseMap = empty, + PseudoRandom = empty, + PcgRandom = empty, + SecureRandom = empty, + VoxelArea = open_table, + VoxelManip = empty, + Raycast = empty, + Settings = empty, + } +} diff --git a/src/luacheck/main.lua b/src/luacheck/main.lua index 730bd118..bb94eb67 100644 --- a/src/luacheck/main.lua +++ b/src/luacheck/main.lua @@ -92,6 +92,7 @@ Links: " luajit - globals of LuaJIT 2.x;\n" .. " ngx_lua - globals of Openresty lua-nginx-module 0.10.10, including standard LuaJIT 2.x globals;\n" .. " love - globals added by LÖVE;\n" .. + " minetest - globals added by minetest;\n" .. " playdate - globals added by the Playdate SDK;\n" .. " busted - globals added by Busted 2.0, by default added for files ending with _spec.lua within spec, " .. "test, and tests subdirectories;\n" ..