Analysis and Preliminary Work for Importing Functionality from Another Project

Adventist Analysis for AARKD ID (Slugs) Work

I wrote Analysis and Preliminary Work for Importing Functionality from Another Project. The long-term plan is to extract that code into a portable chunk of work. We believe many Samvera adopters might be interested in the slugs instead of IDs for application URLs feature.

This feature seems like it should be straightforward; after all it’s relatively easy in a conventional Rails application.

The challenge in a Samvera application is that there are three-and-a-half persistence layers that require coordination: Solr, Fedora Commons, and Postgresql; I count Redis as half a layer for reasons that I’ll explain later.

When working with these persistence layers, we rely on primary keys for maintaining some semblance of referential integrity. And due to long-standing implementation details, we’ve assumed that our routes and relationships will use these primary keys.

However, people rightly want a more meaningful-to-humans Uniform Resource Locator (URL 📖); it helps with Search Engine Optimization (SEO 📖).

in our sprint planning, I was reminded of our first use-case. One of our clients has an application that has a partial implementation of that slug work. The partial implementation has a bug.

My task is to fix the bug; with an eye towards potential gem extraction.

In this note, I’m going to work through the logistics.

The Plan

I’m working through an outline of planned work:

  • Review File Structure
  • Review Override Files
  • Look for Override Comments
  • Look for Neighborhood Changes

Let’s get started.

Review Adventist Code-Base

At Software Services by Scientist.com (SoftServ 📖) we work on numerous Rails applications; and sometimes we need to make application specific adjustments to upstream dependencies. Our Overrides with Decorators and Class Eval playbook article documents our process and approach.

With that in mind, my first order of business is to look for decorator files.

cd ~/git/adventist-dl; find . -type f -name "*_decorator.rb"
./app/presenters/hyrax/homepage_presenter_decorator.rb
./app/factories/bulkrax/object_factory_decorator.rb
./lib/oai/provider/response/list_metadata_formats_decorator.rb
./lib/oai/provider/model_decorator.rb
./lib/hydra/derivatives/processors/image_decorator.rb

Our override pattern leverages Rails::Railtie::Configuration#to_prepare method; so I also want to check what files have a .to_prepare block.

rg "\.to_prepare" ~/git/adventist-dl/config
/Users/jeremy/git/adventist-dl/config/application.rb:    config.to_prepare do

We’ll add that file to our list to check.

Review Override Files

From the above list,

app/presenters/hyrax/homepage_presenter_decorator.rb
[Skip] this introduces a feature flag change unrelated to slugs.
app/factories/bulkrax/object_factory_decorator.rb
[Skip] this introduces a flag to indicate we’re “importing” instead of uploading via the UI.
lib/oai/provider/response/list_metadata_formats_decorator.rb
[Skip] this introduces a record support concept for OAI harvesting.
lib/oai/provider/model_decorator.rb
[Skip] this file references :aark_id, which we use for slugs; but does overlap with the changes we made for the University of Louisville.
lib/hydra/derivatives/processors/image_decorator.rb
[Skip] this introduces image derivative adjustments.
config/application.rb
Looking at this file, we’re only targeting *_decorator files for eager load.

With this preliminary overview, I’m wondering what additional changes were made to handle slugs. I’ll need to dive further into the implementation by looking for override comments.

Look for Override Comments

Not every override can be handled via the decorator pattern. Sometimes we make inline adjustments. Let’s go look for those.

Working on and in software is about getting good at leaving clues for future people; clues about why and what changed. Fortunately we have a preponderance of tools for this: Readme and Changelog documents, Release notes, commit messages, inline comments, merge request discussions, and more. The challenge is finding them.

Which is why documenting procedures and following those procedures becomes vital.

I only want the files to go visit

cd ~/git/adventist-dl && rg "OVERRIDE" ./config -i --files-with-matches
./config/initializers/simple_form.rb
./config/locales/hyrax.en.yml
./config/locales/en.yml

Investigating the Override Comments

From the above list I have my notes:

config/initializers/simple_form.rb
[Skip] comment states the only change is related to presentation of SimpleForm fields.
config/initializers/slug_override.rb
Jackpot! This is the file to explore.
config/locales/hyrax.en.yml
[Skip] Messages related to overriding a static page.
config/locales/en.yml
[Skip] Messages related to overriding Cascading Stylesheet (CSS 📖).

From here forward, let’s use the abbreviated slug_override.rb to represent the config/initializers/slug_override.rb file.

In a superficial look at the slug_override.rb there is considerable overlap to what is in the Louisville code-base.

Look for Neighborhood Changes

From the outward appearances, I see that there is one “interesting” file for this work. What I now want to do is look at files that were updated at the same time as the slug_override.rb file.

Finding How Many Times This Changed

First let’s see how many times we’ve interacted with the slug_override.rb file and who might provide some help:

cd ~/git/adventist-dl ;\
    git log --pretty=format:'%h - %s' config/initializers/slug_override.rb

There are two commits of interest. And when I add the %an to the format, I see that there are two people who I can reach out to if I need further insight and wayfinding.

Finding What Else Changed At the Same Time

Now let’s write a script to find all of the commits associated with the slug_override.rb file. For each of those commits, get the filenames associated with the commit. And create a unique list of those filenames. These are the files of secondary interest.

Below is that script:

cd ~/git/adventist-dl ;\
    git log --pretty=format:'%h' -- config/initializers/slug_override.rb \
	| xargs git show --stat \
	| rg "\w+/\S+" --only-matching \
	| sort \
	| uniq
app/indexers/conference_item_indexer.rb
app/indexers/dataset_indexer.rb
app/indexers/exam_paper_indexer.rb
app/indexers/journal_article_indexer.rb
app/indexers/published_work_indexer.rb
app/indexers/thesis_indexer.rb
app/indexers/work_indexer.rb
app/models/adventist_metadata.rb
app/models/concerns/slug_bug.rb
app/models/conference_item.rb
app/models/dataset.rb
app/models/exam_paper.rb
app/models/generic_work.rb
app/models/image.rb
app/models/journal_article.rb
app/models/published_work.rb
app/models/slug_metadata.rb
app/models/solr_document.rb
app/models/thesis.rb
app/views/records/edit_fields/_default.html.erb
config/initializers/dog_biscuits.rb
config/initializers/slug_override.rb
ops/production-deploy.tmpl.yaml
spec/models/image_spec.rb

Looking at the results I’m relieved to see that we don’t have a lot of related app/views files. There are quite a few files to review.

Next up is looking at the changes to those files for those commits. For that, I’ll use the following script.

cd ~/git/adventist-dl ;\
      git log --pretty=format:'%h' config/initializers/slug_override.rb \
	  | xargs git show

With the above script, I have a pager for reviewing the changes in greater detail.

To give a sense of scope of those two changes, here’s a script and output to see the “shortstats”:

cd ~/git/adventist-dl ;\
    git log --pretty=format:'%h' config/initializers/slug_override.rb \
	| xargs git show --shortstat
commit e7b394b05242be22038cece9c9557cfea65cd923

    Mailer settings

 2 files changed, 39 insertions(+), 16 deletions(-)

commit c068549ec05a0a574aab2081458ecebc7ec45a5a

    Slug exploration

 23 files changed, 252 insertions(+), 72 deletions(-)

This doesn’t look too daunting! Note: I amended the results to remove some details.

And in my experience, I have a tertiary concern to consider: additional changes made to the above list of files that happened after the initial slug_override.rb. In other words, when we introduced the new feature and made changes for that feature, what other changes did we make to files related to the slug_override work.

Let’s build a script to explain what I’m thinking; I’m not going to loop through the above files but will pick one and go with it.

In this script instead of showing all of the files, I’m piping that results to wc -l; which returns the number of lines. In other words the number of files also changed.

cd ~/git/adventist-dl ;\
    git log --pretty=format:'%h' \
	c068549ec05a0a574aab2081458ecebc7ec45a5a~.. \
	app/models/published_work.rb \
	| xargs git show --stat \
	| rg "\w+/\S+" --only-matching \
	| sort \
	| uniq \
	| wc -l
      40

As you can imagine, this creates a graph of potential files of interest. And while I don’t reference all of this, I do use it as potential wayfinding tools.

Conclusion

I again wanted to take time to write-up my approach for orienting to a new code-base with a specific task in mind.

I write to think. And this post is now part of my Personal Knowledge Management (PKM 📖) ecosystem; first as a Denote note then as an exported blog post.

To invoke Richard Feynman: “Notes aren’t a record of my thinking process. They are my thinking process.” This post is my thinking that goes into writing software.

Next Steps

Given that both the Louisville repositories and Adventist repositories have a primary file, I’m going to spend some time working through those two files to look for the conceptual overlap and differences.

Once I have that, I plan to look at how the other related files interact with the central file.

In other words, this post is looking at the big picture and the next steps are looking at the very specific details.

Postscript

This sleuthing exercise highlights the value of atomic commits. In scanning the files that changed, I see that there’s a ops/production-deploy.tmpl.yaml; that file is almost certainly not part of the conceptual changes for the slug_override.rb.

It is not a big deal but does create a minor distraction in reviewing what needs adjusting.