1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-03 07:24:58 +03:00
inform7/inbuild/supervisor-module/Chapter 4/Pipeline Manager.w

144 lines
5 KiB
OpenEdge ABL
Raw Normal View History

2020-02-10 02:10:58 +02:00
[PipelineManager::] Pipeline Manager.
2020-03-31 02:17:21 +03:00
Claiming and creating copies of the pipeline genre: used for pipelines of
code-generation stages.
2020-02-10 02:10:58 +02:00
@h Genre definition.
2020-03-30 15:25:23 +03:00
The |pipeline_genre| can be summarised as follows. Copies consist of single
files. These are recognised by having the filename extension |.interpipeline|.
They are stored in nests, in |N/Pipelines/Title-vVersion.i7x|. Their build
graphs are single vertices with no build or use edges.
2020-02-10 02:10:58 +02:00
2020-03-30 15:25:23 +03:00
=
2020-02-10 02:10:58 +02:00
void PipelineManager::start(void) {
2020-03-10 22:21:55 +02:00
pipeline_genre = Genres::new(I"pipeline", TRUE);
2020-02-10 02:10:58 +02:00
METHOD_ADD(pipeline_genre, GENRE_WRITE_WORK_MTID, PipelineManager::write_work);
METHOD_ADD(pipeline_genre, GENRE_CLAIM_AS_COPY_MTID, PipelineManager::claim_as_copy);
METHOD_ADD(pipeline_genre, GENRE_SEARCH_NEST_FOR_MTID, PipelineManager::search_nest_for);
METHOD_ADD(pipeline_genre, GENRE_COPY_TO_NEST_MTID, PipelineManager::copy_to_nest);
}
void PipelineManager::write_work(inbuild_genre *gen, OUTPUT_STREAM, inbuild_work *work) {
WRITE("%S", work->title);
}
@ Pipelines live in their namesake subdirectory of a nest:
=
pathname *PipelineManager::path_within_nest(inbuild_nest *N) {
if (N == NULL) internal_error("no nest");
return Pathnames::down(N->location, I"Pipelines");
2020-02-10 02:10:58 +02:00
}
@ Pipeline copies are annotated with a structure called an |inform_pipeline|,
which stores data about pipelines used by the Inform compiler.
=
inform_pipeline *PipelineManager::from_copy(inbuild_copy *C) {
if ((C) && (C->edition->work->genre == pipeline_genre)) {
2020-05-05 01:34:55 +03:00
return RETRIEVE_POINTER_inform_pipeline(C->metadata);
2020-02-10 02:10:58 +02:00
}
return NULL;
}
inbuild_copy *PipelineManager::new_copy(inbuild_edition *edition, filename *F,
inbuild_nest *N) {
inbuild_copy *C = Copies::new_in_file(edition, F, NULL);
2020-05-05 01:34:55 +03:00
Pipelines::scan(C);
2020-02-10 02:10:58 +02:00
return C;
}
@h Claiming.
Here |arg| is a textual form of a filename or pathname, such as may have been
supplied at the command line; |ext| is a substring of it, and is its extension
(e.g., |jpg| if |arg| is |Geraniums.jpg|), or is empty if there isn't one;
|directory_status| is true if we know for some reason that this is a directory
not a file, false if we know the reverse, and otherwise not applicable.
2020-03-30 14:23:06 +03:00
An pipeline, for us, simply needs to be a file with extension |.interpipeline|.
2020-02-10 02:10:58 +02:00
=
void PipelineManager::claim_as_copy(inbuild_genre *gen, inbuild_copy **C,
text_stream *arg, text_stream *ext, int directory_status) {
if (directory_status == TRUE) return;
if (Str::eq_insensitive(ext, I"interpipeline")) {
filename *F = Filenames::from_text(arg);
*C = PipelineManager::claim_file_as_copy(F, NULL, NULL);
2020-02-10 02:10:58 +02:00
}
}
inbuild_copy *PipelineManager::claim_file_as_copy(filename *F, text_stream *error_text,
inbuild_nest *N) {
2020-02-10 02:10:58 +02:00
if (TextFiles::exists(F) == FALSE) return NULL;
2020-02-19 22:48:30 +02:00
semantic_version_number V = VersionNumbers::null();
2020-06-28 01:18:54 +03:00
TEMPORARY_TEXT(unext)
2020-02-10 02:10:58 +02:00
Filenames::write_unextended_leafname(unext, F);
inbuild_copy *C = PipelineManager::new_copy(
Editions::new(Works::new_raw(pipeline_genre, unext, NULL), V), F, N);
2020-06-28 01:18:54 +03:00
DISCARD_TEXT(unext)
2020-02-10 02:10:58 +02:00
return C;
}
@h Searching.
Here we look through a nest to find all pipelines matching the supplied
requirements.
=
void PipelineManager::search_nest_for(inbuild_genre *gen, inbuild_nest *N,
inbuild_requirement *req, linked_list *search_results) {
if ((req->work->genre) && (req->work->genre != pipeline_genre)) return;
pathname *P = PipelineManager::path_within_nest(N);
linked_list *L = Directories::listing(P);
text_stream *entry;
LOOP_OVER_LINKED_LIST(entry, text_stream, L) {
if (Platform::is_folder_separator(Str::get_last_char(entry)) == FALSE) {
filename *F = Filenames::in(P, entry);
inbuild_copy *C = PipelineManager::claim_file_as_copy(F, NULL, N);
if ((C) && (Requirements::meets(C->edition, req))) {
Nests::add_search_result(search_results, N, C, req);
2020-02-10 02:10:58 +02:00
}
}
}
}
@h Copying.
Now the task is to copy a pipeline into place in a nest. This is easy,
since a pipeline is a single file; to sync, we just overwrite.
=
2020-03-10 02:08:35 +02:00
filename *PipelineManager::filename_in_nest(inbuild_nest *N, inbuild_edition *E) {
2020-06-28 01:18:54 +03:00
TEMPORARY_TEXT(leaf)
2020-03-10 02:08:35 +02:00
Editions::write_canonical_leaf(leaf, E);
WRITE_TO(leaf, ".interpipeline");
filename *F = Filenames::in(PipelineManager::path_within_nest(N), leaf);
2020-06-28 01:18:54 +03:00
DISCARD_TEXT(leaf)
2020-02-10 02:10:58 +02:00
return F;
}
void PipelineManager::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inbuild_nest *N,
int syncing, build_methodology *meth) {
2020-03-10 02:08:35 +02:00
filename *F = PipelineManager::filename_in_nest(N, C->edition);
2020-02-10 02:10:58 +02:00
if (TextFiles::exists(F)) {
2020-03-29 19:39:17 +03:00
if (syncing == FALSE) { Copies::overwrite_error(C, N); return; }
2020-02-10 02:10:58 +02:00
} else {
if (meth->methodology == DRY_RUN_METHODOLOGY) {
2020-06-28 01:18:54 +03:00
TEMPORARY_TEXT(command)
2020-02-10 02:10:58 +02:00
WRITE_TO(command, "mkdir -p ");
Shell::quote_path(command, Filenames::up(F));
2020-02-10 02:10:58 +02:00
WRITE_TO(STDOUT, "%S\n", command);
2020-06-28 01:18:54 +03:00
DISCARD_TEXT(command)
2020-02-10 02:10:58 +02:00
} else {
Pathnames::create_in_file_system(N->location);
Pathnames::create_in_file_system(Filenames::up(F));
2020-02-10 02:10:58 +02:00
}
}
2020-06-28 01:18:54 +03:00
TEMPORARY_TEXT(command)
2020-02-10 02:10:58 +02:00
WRITE_TO(command, "cp -f ");
Shell::quote_file(command, C->location_if_file);
Shell::quote_file(command, F);
BuildSteps::shell(command, meth);
2020-06-28 01:18:54 +03:00
DISCARD_TEXT(command)
2020-02-10 02:10:58 +02:00
}