Project

General

Profile

Download (5.63 KB) Statistics
| Branch: | Tag: | Revision:

haketilo / common / entities.js @ ad69f9c8

1
/**
2
 * This file is part of Haketilo.
3
 *
4
 * Function: Operations on resources and mappings.
5
 *
6
 * Copyright (C) 2021 Wojtek Kosior <koszko@koszko.org>
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * As additional permission under GNU GPL version 3 section 7, you
19
 * may distribute forms of that code without the copy of the GNU
20
 * GPL normally required by section 4, provided you include this
21
 * license notice and, in case of non-source distribution, a URL
22
 * through which recipients can access the Corresponding Source.
23
 * If you modify file(s) with this exception, you may extend this
24
 * exception to your version of the file(s), but you are not
25
 * obligated to do so. If you do not wish to do so, delete this
26
 * exception statement from your version.
27
 *
28
 * As a special exception to the GPL, any HTML file which merely
29
 * makes function calls to this code, and for that purpose
30
 * includes it by reference shall be deemed a separate work for
31
 * copyright law purposes. If you modify this code, you may extend
32
 * this exception to your version of the code, but you are not
33
 * obligated to do so. If you do not wish to do so, delete this
34
 * exception statement from your version.
35
 *
36
 * You should have received a copy of the GNU General Public License
37
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
38
 *
39
 * I, Wojtek Kosior, thereby promise not to sue for violation of this file's
40
 * license. Although I request that you do not make use of this code in a
41
 * proprietary program, I am not going to enforce this in court.
42
 */
43

    
44
/*
45
 * Convert ver_str into an array representation, e.g. for ver_str="4.6.13.0"
46
 * return [4, 6, 13, 0].
47
 */
48
const parse_version = ver_str => ver_str.split(".").map(n => parseInt(n));
49

    
50
/*
51
 * ver is an array of integers. rev is an optional integer. Produce string
52
 * representation of version (optionally with revision number), like:
53
 *     1.2.3-5
54
 * No version normalization is performed.
55
 */
56
const version_string = (ver, rev=0) => ver.join(".") + (rev ? `-${rev}` : "");
57
#EXPORT version_string
58

    
59
/*
60
 * This function overloads on the number of arguments. If one argument is
61
 * passed, it is an item definition (it need not be complete, only identifier,
62
 * version and, if applicable, revision properties are relevant). If two or
63
 * three arguments are given, they are in order: item identifier, item version
64
 * and item revision.
65
 * Returned is a string identifying this version of item.
66
 */
67
function item_id_string(...args) {
68
    let def = args[0]
69
    if (args.length > 1)
70
	def = {identifier: args[0], version: args[1], revision: args[2]};
71
    return !Array.isArray(def.version) ? def.identifier :
72
	`${def.identifier}-${version_string(def.version, def.revision)}`;
73
}
74
#EXPORT item_id_string
75

    
76
/* vers should be an array of comparable values. Return the greatest one. */
77
const max = vals => vals.reduce((v1, v2) => v1 > v2 ? v1 : v2);
78

    
79
/*
80
 * versioned_item should be a dict with keys being version strings and values
81
 * being definitions of the respective versions of a single resource/mapping.
82
 * Example:
83
 *     {
84
 *         "1": {
85
 *             version: [1]//,
86
 *             // more stuff
87
 *         },
88
 *         "1.1": {
89
 *             version: [1, 1]//,
90
 *             // more stuff
91
 *         }
92
 *      }
93
 *
94
 * Returns the definition with the highest version.
95
 */
96
function get_newest_version(versioned_item)
97
{
98
    const best_ver = max(Object.keys(versioned_item).map(parse_version));
99
    return versioned_item[version_string(best_ver)];
100
}
101
#EXPORT get_newest_version AS get_newest
102

    
103
/*
104
 * Returns true if the argument is a nonempty array of numbers without trailing
105
 * zeros.
106
 */
107
function is_valid_version(version) {
108
    return Array.isArray(version) && version.length > 0 &&
109
	version.every(n => typeof n === "number") &&
110
	version[version.length - 1] !== 0;
111
}
112
#EXPORT is_valid_version
113

    
114
/*
115
 * item is a definition of a resource or mapping. Yield all file references
116
 * (objects with `file` and `sha256` properties) this definition has.
117
 */
118
function* get_used_files(item)
119
{
120
    for (const file of item.source_copyright)
121
	yield file;
122

    
123
    if (item.type === "resource") {
124
	for (const file of item.scripts || [])
125
	    yield file;
126
    }
127
}
128
#EXPORT get_used_files AS get_files
129

    
130
#IF NEVER
131

    
132
/*
133
 * Note: the functions below were overeagerly written and are not used now but
134
 * might prove useful to once we add more functionalities and are hence kept...
135
 */
136

    
137
/*
138
 * Clone recursively all objects. Leave other items (arrays, strings) untouched.
139
 */
140
function deep_object_copy(object)
141
{
142
    const orig = {object};
143
    const result = {};
144
    const to_copy = [[orig, {}]];
145

    
146
    while (to_copy.length > 0) {
147
	const [object, copy] = to_copy.pop();
148

    
149
	for (const [key, value] of Object.entries(object)) {
150
	    copy[key] = value;
151

    
152
	    if (typeof value === "object" && !Array.isArray(value)) {
153
		const value_copy = {};
154
		to_copy.push([value, value_copy]);
155
		copy[key] = value_copy;
156
	    }
157
	}
158
    }
159

    
160
    return result.orig;
161
}
162

    
163
/* helper function for normalize_version() */
164
const version_reductor = (acc, n) => [...(n || acc.length ? [n] : []), ...acc];
165
/*
166
 * ver is an array of integers. Strip right-most zeroes from ver.
167
 *
168
 * Returns a *new* array. Doesn't modify its argument.
169
 */
170
const normalize_version = ver => ver.reduceRight(version_reductor, []);
171

    
172
#ENDIF
(3-3/10)