Fix language selection broken after po file merges
[project/luci.git] / libs / lpk / luasrc / lpk / core.lua
1 module("luci.lpk.core", package.seeall)
2 require("luci.util")
3
4 Task = luci.util.class()
5
6 function Task.__init__(self, machine, register, start)
7 self.machine = machine
8
9 -- The queue that has to be processed
10 self.work = {start}
11
12 -- The queue that has to be processed in case of rollback
13 self.done = {}
14
15 -- The Task register
16 self.register = register
17 end
18
19 function Task.rollback(self)
20 if #self.done < 1 then
21 return false
22 end
23
24 local state = table.remove(self.done)
25 if not state.rollback then
26 return true
27 end
28
29 local ret, err = pcall(state.rollback, state, self.register)
30
31 if ret then
32 return true
33 else
34 return false, err
35 end
36 end
37
38 function Task.step(self)
39 local state = table.remove(self.work)
40 local ret, next = pcall(state.process, self.register)
41
42 if ret then
43 if next then
44 local nstate = self.machine:state(next)
45 if nstate then
46 table.insert(self.work, state)
47 table.insert(self.work, nstate)
48 else
49 self.register.error = 2
50 self.register.errstr = "Unknown state: " .. next
51 return false
52 end
53 else
54 table.insert(self.done, state)
55 end
56
57 return #self.work > 0
58 else
59 self.register.error = next
60 return false
61 end
62 end
63
64 function Task.perform(self)
65 while self:step() do
66 end
67
68 if not self.register.error then
69 return true
70 else
71 local stat, err
72 repeat
73 stat, err = self:rollback()
74 until not stat
75
76 if err then
77 self.register.errstr = err
78 self.register.error = 2
79 end
80
81 return false
82 end
83 end
84
85
86 Machine = luci.util.class()
87
88 function Machine.__init__(self, namespace)
89 self.namespace = namespace or _NAME
90 end
91
92 function Machine.state(self, name)
93 local ret, state = pcall(require, self.namespace .. "." .. name)
94 return ret and state
95 end
96
97 function Machine.task(self, name, ...)
98 local start = self:state(name)
99
100 if type(start) ~= "table" or not start.entry then
101 return false, "No such command: " .. name
102 end
103
104 local register = {}
105
106 return start.entry(register, ...) and Task(self, register, start)
107 end