mirror of
https://github.com/ganelson/inform.git
synced 2024-06-26 04:00:43 +03:00
Copy and sync to nests
This commit is contained in:
parent
3842c4276c
commit
5faf2f8557
|
@ -11,6 +11,8 @@ this plan out.
|
|||
@e GRAPH_TTASK
|
||||
@e BUILD_TTASK
|
||||
@e REBUILD_TTASK
|
||||
@e COPY_TO_TTASK
|
||||
@e SYNC_TO_TTASK
|
||||
|
||||
=
|
||||
pathname *path_to_inbuild = NULL;
|
||||
|
@ -21,6 +23,7 @@ linked_list *find_list = NULL;
|
|||
int inbuild_task = INSPECT_TTASK;
|
||||
int dry_run_mode = FALSE;
|
||||
linked_list *targets = NULL; /* of |inbuild_copy| */
|
||||
inbuild_nest *destination_nest = NULL;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Foundation::start();
|
||||
|
@ -60,6 +63,8 @@ int main(int argc, char **argv) {
|
|||
case GRAPH_TTASK: Graphs::describe(STDOUT, C->graph, TRUE); break;
|
||||
case BUILD_TTASK: Graphs::build(C->graph, BM); break;
|
||||
case REBUILD_TTASK: Graphs::rebuild(C->graph, BM); break;
|
||||
case COPY_TO_TTASK: if (destination_nest) Nests::copy_to(C, destination_nest, FALSE); break;
|
||||
case SYNC_TO_TTASK: if (destination_nest) Nests::copy_to(C, destination_nest, TRUE); break;
|
||||
}
|
||||
}
|
||||
InbuildModule::end();
|
||||
|
@ -78,11 +83,17 @@ int main(int argc, char **argv) {
|
|||
@e CONTENTS_OF_CLSW
|
||||
@e NEST_CLSW
|
||||
@e FIND_CLSW
|
||||
@e COPY_TO_CLSW
|
||||
@e SYNC_TO_CLSW
|
||||
|
||||
@<Read the command line@> =
|
||||
CommandLine::declare_heading(
|
||||
L"[[Purpose]]\n\n"
|
||||
L"usage: inbuild [-TASK] TARGET1 TARGET2 ...\n");
|
||||
CommandLine::declare_switch(COPY_TO_CLSW, L"copy-to", 2,
|
||||
L"copy target(s) to nest X");
|
||||
CommandLine::declare_switch(SYNC_TO_CLSW, L"sync-to", 2,
|
||||
L"forcibly copy target(s) to nest X, even if prior version already there");
|
||||
CommandLine::declare_switch(BUILD_CLSW, L"build", 1,
|
||||
L"incrementally build target(s)");
|
||||
CommandLine::declare_switch(REBUILD_CLSW, L"rebuild", 1,
|
||||
|
@ -117,6 +128,12 @@ void Main::option(int id, int val, text_stream *arg, void *state) {
|
|||
case NEST_CLSW: Nests::add_to_search_sequence(nest_list,
|
||||
Nests::new(Pathnames::from_text(arg))); break;
|
||||
case FIND_CLSW: ADD_TO_LINKED_LIST(Str::duplicate(arg), text_stream, find_list); break;
|
||||
case COPY_TO_CLSW: inbuild_task = COPY_TO_TTASK;
|
||||
destination_nest = Nests::new(Pathnames::from_text(arg));
|
||||
break;
|
||||
case SYNC_TO_CLSW: inbuild_task = SYNC_TO_TTASK;
|
||||
destination_nest = Nests::new(Pathnames::from_text(arg));
|
||||
break;
|
||||
default: internal_error("unimplemented switch");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ few of these.
|
|||
|
||||
@e GENRE_WRITE_WORK_MTID
|
||||
@e GENRE_LOCATION_IN_NEST_MTID
|
||||
@e GENRE_COPY_TO_NEST_MTID
|
||||
|
||||
=
|
||||
typedef struct inbuild_genre {
|
||||
|
@ -18,6 +19,7 @@ typedef struct inbuild_genre {
|
|||
|
||||
VMETHOD_TYPE(GENRE_WRITE_WORK_MTID, inbuild_genre *gen, text_stream *OUT, inbuild_work *work)
|
||||
VMETHOD_TYPE(GENRE_LOCATION_IN_NEST_MTID, inbuild_genre *gen, inbuild_nest *N, inbuild_requirement *req, linked_list *search_results)
|
||||
VMETHOD_TYPE(GENRE_COPY_TO_NEST_MTID, inbuild_genre *gen, inbuild_copy *C, inbuild_nest *N, int syncing)
|
||||
|
||||
@ =
|
||||
inbuild_genre *Model::genre(text_stream *name) {
|
||||
|
|
|
@ -58,3 +58,7 @@ void Nests::locate(inbuild_requirement *req, linked_list *search_list, linked_li
|
|||
VMETHOD_CALL(req->work->genre, GENRE_LOCATION_IN_NEST_MTID, N, req, results);
|
||||
}
|
||||
}
|
||||
|
||||
void Nests::copy_to(inbuild_copy *C, inbuild_nest *destination_nest, int syncing) {
|
||||
VMETHOD_CALL(C->edition->work->genre, GENRE_COPY_TO_NEST_MTID, C, destination_nest, syncing);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ void Kits::start(void) {
|
|||
kit_genre = Model::genre(I"kit");
|
||||
METHOD_ADD(kit_genre, GENRE_WRITE_WORK_MTID, Kits::write_copy);
|
||||
METHOD_ADD(kit_genre, GENRE_LOCATION_IN_NEST_MTID, Kits::location_in_nest);
|
||||
METHOD_ADD(kit_genre, GENRE_COPY_TO_NEST_MTID, Kits::copy_to_nest);
|
||||
}
|
||||
|
||||
void Kits::write_copy(inbuild_genre *gen, OUTPUT_STREAM, inbuild_work *work) {
|
||||
|
@ -28,6 +29,26 @@ void Kits::location_in_nest(inbuild_genre *gen, inbuild_nest *N, inbuild_require
|
|||
}
|
||||
}
|
||||
|
||||
void Kits::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inbuild_nest *N, int syncing) {
|
||||
// Model::write_copy(STDOUT, C); PRINT(" --> %p %S\n", N->location, syncing?I"syncing":I"copying");
|
||||
pathname *dest_kit = Pathnames::subfolder(N->location, I"Inter");
|
||||
dest_kit = Pathnames::subfolder(dest_kit, C->edition->work->name);
|
||||
|
||||
filename *dest_kit_metadata = Filenames::in_folder(dest_kit, I"kit_metadata.txt");
|
||||
if (TextFiles::exists(dest_kit_metadata)) {
|
||||
if (syncing == FALSE) {
|
||||
Errors::with_text("already present in nest (use -sync-to not -copy-to to overwrite)",
|
||||
C->edition->work->name);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Pathnames::create_in_file_system(N->location);
|
||||
Pathnames::create_in_file_system(Pathnames::subfolder(N->location, I"Inter"));
|
||||
Pathnames::create_in_file_system(dest_kit);
|
||||
}
|
||||
Pathnames::rsync(C->location_if_path, dest_kit);
|
||||
}
|
||||
|
||||
typedef struct inform_kit {
|
||||
struct inbuild_copy *as_copy;
|
||||
struct text_stream *name;
|
||||
|
@ -58,9 +79,11 @@ typedef struct element_activation {
|
|||
MEMORY_MANAGEMENT
|
||||
} element_activation;
|
||||
|
||||
pathname *Kits::find(text_stream *name, int N, pathname **PP) {
|
||||
for (int i=0; i<N; i++) {
|
||||
pathname *P = Pathnames::subfolder(PP[i], name);
|
||||
pathname *Kits::find(text_stream *name, linked_list *nest_list) {
|
||||
inbuild_nest *N;
|
||||
LOOP_OVER_LINKED_LIST(N, inbuild_nest, nest_list) {
|
||||
pathname *P = Pathnames::subfolder(N->location, I"Inter");
|
||||
P = Pathnames::subfolder(P, name);
|
||||
filename *F = Filenames::in_folder(P, I"kit_metadata.txt");
|
||||
if (TextFiles::exists(F)) return P;
|
||||
}
|
||||
|
@ -138,8 +161,8 @@ void Kits::read_contents(text_stream *text, text_file_position *tfp, void *state
|
|||
Regexp::dispose_of(&mr);
|
||||
}
|
||||
|
||||
inform_kit *Kits::load(text_stream *name, int N, pathname **PP) {
|
||||
pathname *P = Kits::find(name, N, PP);
|
||||
inform_kit *Kits::load(text_stream *name, linked_list *nest_list) {
|
||||
pathname *P = Kits::find(name, nest_list);
|
||||
if (P == NULL) Errors::fatal_with_text("cannot find kit", name);
|
||||
return Kits::load_at(name, P);
|
||||
}
|
||||
|
@ -208,7 +231,7 @@ int Kits::loaded(text_stream *name) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void Kits::perform_ittt(int N, pathname **PP) {
|
||||
void Kits::perform_ittt(linked_list *nest_list) {
|
||||
int changes_made = TRUE;
|
||||
while (changes_made) {
|
||||
changes_made = FALSE;
|
||||
|
@ -218,7 +241,7 @@ void Kits::perform_ittt(int N, pathname **PP) {
|
|||
LOOP_OVER_LINKED_LIST(ITTT, inform_kit_ittt, K->ittt)
|
||||
if ((Kits::loaded(ITTT->then_name) == FALSE) &&
|
||||
(Kits::loaded(ITTT->if_name) == ITTT->if_included)) {
|
||||
Kits::load(ITTT->then_name, N, PP);
|
||||
Kits::load(ITTT->then_name, nest_list);
|
||||
changes_made = TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -237,15 +260,15 @@ void Kits::request(text_stream *name) {
|
|||
}
|
||||
|
||||
#ifdef CORE_MODULE
|
||||
void Kits::determine(int N, pathname **PP) {
|
||||
void Kits::determine(linked_list *nest_list) {
|
||||
if (kits_requested == NULL) Kits::request(I"CommandParserKit");
|
||||
Kits::request(I"BasicInformKit");
|
||||
NaturalLanguages::request_required_kits();
|
||||
text_stream *kit_name;
|
||||
LOOP_OVER_LINKED_LIST(kit_name, text_stream, kits_requested)
|
||||
Kits::load(kit_name, N, PP);
|
||||
Kits::load(kit_name, nest_list);
|
||||
|
||||
Kits::perform_ittt(N, PP);
|
||||
Kits::perform_ittt(nest_list);
|
||||
|
||||
kits_to_include = NEW_LINKED_LIST(inform_kit);
|
||||
for (int p=0; p<100; p++) {
|
||||
|
|
|
@ -225,7 +225,7 @@ list is not exhaustive.
|
|||
doc_references_top = lexer_wordcount - 1;
|
||||
|
||||
@<Work out our kit requirements@> =
|
||||
Kits::determine(NO_FS_AREAS, pathname_of_inter_resources);
|
||||
Kits::determine(I7_nest_list);
|
||||
|
||||
@<Perform lexical analysis@> =
|
||||
ProgressBar::update_progress_bar(0, 0);
|
||||
|
|
|
@ -21,6 +21,7 @@ char *AREA_NAME[3] = { "from .materials", "installed", "built in" };
|
|||
@ Now for the folders:
|
||||
|
||||
= (early code)
|
||||
linked_list *I7_nest_list = NULL;
|
||||
pathname *pathname_of_area[NO_FS_AREAS] = { NULL, NULL, NULL };
|
||||
pathname *pathname_of_extensions[NO_FS_AREAS] = { NULL, NULL, NULL };
|
||||
pathname *pathname_of_inter_resources[NO_FS_AREAS] = { NULL, NULL, NULL };
|
||||
|
@ -133,6 +134,13 @@ int Locations::set_defaults(int census_mode) {
|
|||
Problems::Fatal::issue("Except in census mode, source text must be supplied");
|
||||
if ((census_mode) && (filename_of_i7_source))
|
||||
Problems::Fatal::issue("In census mode, no source text may be supplied");
|
||||
I7_nest_list = NEW_LINKED_LIST(inbuild_nest);
|
||||
if (pathname_of_area[MATERIALS_FS_AREA])
|
||||
ADD_TO_LINKED_LIST(Nests::new(pathname_of_area[MATERIALS_FS_AREA]), inbuild_nest, I7_nest_list);
|
||||
if (pathname_of_area[EXTERNAL_FS_AREA])
|
||||
ADD_TO_LINKED_LIST(Nests::new(pathname_of_area[EXTERNAL_FS_AREA]), inbuild_nest, I7_nest_list);
|
||||
if (pathname_of_area[INTERNAL_FS_AREA])
|
||||
ADD_TO_LINKED_LIST(Nests::new(pathname_of_area[INTERNAL_FS_AREA]), inbuild_nest, I7_nest_list);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -487,28 +487,23 @@ integration: \
|
|||
$(INTERNAL)/Languages/English/Basic.indext \
|
||||
$(SRULESINPLACE) \
|
||||
$(BINFORMINPLACE) \
|
||||
$(INTERNAL)/Inter/BasicInformKit/arch-32d.interb \
|
||||
$(INTERNAL)/Inter/BasicInformKit/kit_metadata.txt \
|
||||
$(INTERNAL)/Inter/EnglishLanguageKit/arch-32d.interb \
|
||||
$(INTERNAL)/Inter/EnglishLanguageKit/kit_metadata.txt \
|
||||
$(INTERNAL)/Inter/BasicInformExtrasKit/arch-32d.interb \
|
||||
$(INTERNAL)/Inter/BasicInformExtrasKit/kit_metadata.txt \
|
||||
$(INTERNAL)/Inter/WorldModelKit/arch-32d.interb \
|
||||
$(INTERNAL)/Inter/WorldModelKit/kit_metadata.txt \
|
||||
$(INTERNAL)/Inter/CommandParserKit/arch-32d.interb \
|
||||
$(INTERNAL)/Inter/CommandParserKit/kit_metadata.txt \
|
||||
kitsintegration \
|
||||
$(INTERNAL)/Inter/default.interpipeline \
|
||||
$(DOCEXEMPLUM) \
|
||||
$(INTERNALEXEMPLUM) \
|
||||
$(IMAGESEXEMPLUM) \
|
||||
$(RTPEXEMPLUM)
|
||||
|
||||
.PHONY: kitsintegration
|
||||
kitsintegration:
|
||||
$(call transfer-kits)
|
||||
|
||||
.PHONY: forceintegration
|
||||
forceintegration:
|
||||
$(call transfer-intools)
|
||||
$(call transfer-preform)
|
||||
$(call transfer-standard-rules)
|
||||
$(call transfer-i6-template)
|
||||
$(call transfer-kits)
|
||||
$(call transfer-inter-resources)
|
||||
$(call transfer-internal-tree)
|
||||
$(call transfer-images)
|
||||
|
@ -595,114 +590,8 @@ endef
|
|||
|
||||
# (d) Copying the I6 template into the app
|
||||
|
||||
$(INTERNAL)/Inter/WorldModelKit/arch-32d.interb: \
|
||||
inform7/Internal/Inter/WorldModelKit/arch-32d.interb
|
||||
$(call transfer-i6-template)
|
||||
|
||||
$(INTERNAL)/Inter/CommandParserKit/arch-32d.interb: \
|
||||
inform7/Internal/Inter/CommandParserKit/arch-32d.interb
|
||||
$(call transfer-i6-template)
|
||||
|
||||
$(INTERNAL)/Inter/BasicInformKit/arch-32d.interb: \
|
||||
inform7/Internal/Inter/BasicInformKit/arch-32d.interb
|
||||
$(call transfer-i6-template)
|
||||
|
||||
$(INTERNAL)/Inter/BasicInformKit/kinds/*.kindt: \
|
||||
inform7/Internal/Inter/BasicInformKit/kinds/*.kindt
|
||||
$(call transfer-i6-template)
|
||||
|
||||
$(INTERNAL)/Inter/BasicInformExtrasKit/arch-32d.interb: \
|
||||
inform7/Internal/Inter/BasicInformExtrasKit/arch-32d.interb
|
||||
$(call transfer-i6-template)
|
||||
|
||||
$(INTERNAL)/Inter/BasicInformExtrasKit/kinds/*.kindt: \
|
||||
inform7/Internal/Inter/BasicInformExtrasKit/kinds/*.kindt
|
||||
$(call transfer-i6-template)
|
||||
|
||||
$(INTERNAL)/Inter/EnglishLanguageKit/arch-32d.interb: \
|
||||
inform7/Internal/Inter/EnglishLanguageKit/arch-32d.interb
|
||||
$(call transfer-i6-template)
|
||||
|
||||
$(INTERNAL)/Inter/BasicInformKit/kit_metadata.txt: \
|
||||
inform7/Internal/Inter/BasicInformKit/kit_metadata.txt
|
||||
$(call transfer-i6-template)
|
||||
|
||||
$(INTERNAL)/Inter/BasicInformExtrasKit/kit_metadata.txt: \
|
||||
inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.txt
|
||||
$(call transfer-i6-template)
|
||||
|
||||
$(INTERNAL)/Inter/EnglishLanguageKit/kit_metadata.txt: \
|
||||
inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.txt
|
||||
$(call transfer-i6-template)
|
||||
|
||||
$(INTERNAL)/Inter/WorldModelKit/kit_metadata.txt: \
|
||||
inform7/Internal/Inter/WorldModelKit/kit_metadata.txt
|
||||
$(call transfer-i6-template)
|
||||
|
||||
$(INTERNAL)/Inter/WorldModelKit/kinds/*.kindt: \
|
||||
inform7/Internal/Inter/WorldModelKit/kinds/*.kindt
|
||||
$(call transfer-i6-template)
|
||||
|
||||
$(INTERNAL)/Inter/CommandParserKit/kit_metadata.txt: \
|
||||
inform7/Internal/Inter/CommandParserKit/kit_metadata.txt
|
||||
$(call transfer-i6-template)
|
||||
|
||||
$(INTERNAL)/Inter/CommandParserKit/kinds/*.kindt: \
|
||||
inform7/Internal/Inter/CommandParserKit/kinds/*.kindt
|
||||
$(call transfer-i6-template)
|
||||
|
||||
# The I6 template could be tangled by inweb, but we don't do so: instead the
|
||||
# tangling happens at run-time and is done by Core Inform on the fly. So the
|
||||
# build process consists only of copying it:
|
||||
|
||||
define transfer-i6-template
|
||||
mkdir -p "$(INTERNAL)/Inter"
|
||||
rm -f $(INTERNAL)/Inter/*.i6t
|
||||
cp -R -f inform7/Internal/Inter/*.interpipeline $(INTERNAL)/Inter
|
||||
mkdir -p "$(INTERNAL)/Inter/WorldModelKit"
|
||||
mkdir -p "$(INTERNAL)/Inter/WorldModelKit/source"
|
||||
rm -f $(INTERNAL)/Inter/WorldModelKit/Sections/*.i6t
|
||||
rm -f $(INTERNAL)/Inter/WorldModelKit/*.interb
|
||||
cp -R -f inform7/Internal/Inter/WorldModelKit/Sections/*.i6t $(INTERNAL)/Inter/WorldModelKit/source
|
||||
cp -R -f inform7/Internal/Inter/WorldModelKit/*.interb $(INTERNAL)/Inter/WorldModelKit
|
||||
cp -R -f inform7/Internal/Inter/WorldModelKit/kit_metadata.txt $(INTERNAL)/Inter/WorldModelKit
|
||||
mkdir -p "$(INTERNAL)/Inter/CommandParserKit"
|
||||
mkdir -p "$(INTERNAL)/Inter/CommandParserKit/source"
|
||||
rm -f $(INTERNAL)/Inter/CommandParserKit/Sections/*.i6t
|
||||
rm -f $(INTERNAL)/Inter/CommandParserKit/*.interb
|
||||
cp -R -f inform7/Internal/Inter/CommandParserKit/Sections/*.i6t $(INTERNAL)/Inter/CommandParserKit/source
|
||||
cp -R -f inform7/Internal/Inter/CommandParserKit/*.interb $(INTERNAL)/Inter/CommandParserKit
|
||||
cp -R -f inform7/Internal/Inter/CommandParserKit/kit_metadata.txt $(INTERNAL)/Inter/CommandParserKit
|
||||
mkdir -p "$(INTERNAL)/Inter/BasicInformKit"
|
||||
mkdir -p "$(INTERNAL)/Inter/BasicInformKit/source"
|
||||
rm -f $(INTERNAL)/Inter/BasicInformKit/Sections/*.i6t
|
||||
rm -f $(INTERNAL)/Inter/BasicInformKit/*.interb
|
||||
cp -R -f inform7/Internal/Inter/BasicInformKit/Sections/*.i6t $(INTERNAL)/Inter/BasicInformKit/source
|
||||
cp -R -f inform7/Internal/Inter/BasicInformKit/*.interb $(INTERNAL)/Inter/BasicInformKit
|
||||
cp -R -f inform7/Internal/Inter/BasicInformKit/kit_metadata.txt $(INTERNAL)/Inter/BasicInformKit
|
||||
mkdir -p "$(INTERNAL)/Inter/BasicInformExtrasKit"
|
||||
mkdir -p "$(INTERNAL)/Inter/BasicInformExtrasKit/source"
|
||||
rm -f $(INTERNAL)/Inter/BasicInformExtrasKit/Sections/*.i6t
|
||||
rm -f $(INTERNAL)/Inter/BasicInformExtrasKit/*.interb
|
||||
cp -R -f inform7/Internal/Inter/BasicInformExtrasKit/Sections/*.i6t $(INTERNAL)/Inter/BasicInformExtrasKit/source
|
||||
cp -R -f inform7/Internal/Inter/BasicInformExtrasKit/*.interb $(INTERNAL)/Inter/BasicInformExtrasKit
|
||||
cp -R -f inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.txt $(INTERNAL)/Inter/BasicInformExtrasKit
|
||||
mkdir -p "$(INTERNAL)/Inter/EnglishLanguageKit"
|
||||
mkdir -p "$(INTERNAL)/Inter/EnglishLanguageKit/source"
|
||||
rm -f $(INTERNAL)/Inter/EnglishLanguageKit/Sections/*.i6t
|
||||
rm -f $(INTERNAL)/Inter/EnglishLanguageKit/*.interb
|
||||
cp -R -f inform7/Internal/Inter/EnglishLanguageKit/Sections/*.i6t $(INTERNAL)/Inter/EnglishLanguageKit/source
|
||||
cp -R -f inform7/Internal/Inter/EnglishLanguageKit/*.interb $(INTERNAL)/Inter/EnglishLanguageKit
|
||||
cp -R -f inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.txt $(INTERNAL)/Inter/EnglishLanguageKit
|
||||
mkdir -p "$(INTERNAL)/Inter/BasicInformKit/kinds"
|
||||
rm -f $(INTERNAL)/Inter/BasicInformKit/kinds/*.kindt
|
||||
cp -R -f inform7/Internal/Inter/BasicInformKit/kinds/*.kindt $(INTERNAL)/Inter/BasicInformKit/kinds
|
||||
mkdir -p "$(INTERNAL)/Inter/WorldModelKit/kinds"
|
||||
rm -f $(INTERNAL)/Inter/WorldModelKit/kinds/*.kindt
|
||||
cp -R -f inform7/Internal/Inter/WorldModelKit/kinds/*.kindt $(INTERNAL)/Inter/WorldModelKit/kinds
|
||||
mkdir -p "$(INTERNAL)/Inter/CommandParserKit/kinds"
|
||||
rm -f $(INTERNAL)/Inter/CommandParserKit/kinds/*.kindt
|
||||
cp -R -f inform7/Internal/Inter/CommandParserKit/kinds/*.kindt $(INTERNAL)/Inter/CommandParserKit/kinds
|
||||
define transfer-kits
|
||||
$(INBUILDX) -sync-to $(INTERNAL) -contents-of inform7/Internal/Inter
|
||||
endef
|
||||
|
||||
$(INTERNAL)/Inter/default.interpipeline: inform7/Internal/Inter/*.interpipeline
|
||||
|
|
Loading…
Reference in a new issue