DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Trending

  • AI-Driven Root Cause Analysis in SRE: Enhancing Incident Resolution
  • Designing a Java Connector for Software Integrations
  • Customer 360: Fraud Detection in Fintech With PySpark and ML
  • Mastering Advanced Aggregations in Spark SQL

Makefiles For Modern Development

1976 in your stack? It’s likelier than you think.

By 
Peter Valdez user avatar
Peter Valdez
·
Apr. 02, 22 · Tutorial
Likes (5)
Comment
Save
Tweet
Share
8.5K Views

Join the DZone community and get the full member experience.

Join For Free

Having local workflows line up all of your integrations is very worthwhile, but can be a pain to set up. As starting points for making new apps, developers can check out these recently released starter repos.

In this article, we’ll focus on one of the key pieces of the starter repo: the Makefile.

Why Makefiles?

Languages usually have their own task runners, often embedded in the language’s package manager (e.g. npm for node, poetry for Python). If you use those programs to run the development workflows, though, that means you’ll need to learn a new tool for each language with which you interact.

Using Makefiles as an abstraction above any language-specific tooling allows for easy upgrading of that tooling without having to teach your team how to use a new CLI. This way, they can just keep running the same Make commands they’re used to.

A more subtle benefit is that Makefiles serve as documentation for the workflows and actions needed for any project.

Finally, Makefiles have been in use since 1976, so they’re as battle-tested as can be.

Makefile Example

Let’s take a look at the actual Makefile for our repo, section by section.

1. Main Development Workflow

develop: clean build migrations.upgrade run

clean:
    docker-compose rm -vf

build:
    docker-compose build

run:
    docker-compose up

These are the core functions that developers will be running over and over:

  • make clean to stop any running service
  • make build to re-build your images with updated code
  • make run to run the containers

We can combine each of those actions to form the main command that developers will run over and over:

  • make develop which runs clean, build, and run (and upgrades migrations)

2. Shell Commands

 frontend-shell:
    docker-compose run frontend \
      sh

backend-shell:
    docker-compose run worker \
      sh

python-shell:
    docker-compose run worker \
      poetry run flask shell
  • These are convenience methods to get each of the shells you’ll need for this project:
    • make frontend-shell gets you a Bash shell in the node container
    • make backend-shell gets you a Bash shell in the Python container
    • make python-shell gets you a Python shell in the Python container

3. Database Commands

postgres.data.delete: clean
    docker volume rm $(VOLUME)_postgres

postgres.start:
    docker-compose up -d postgres
    docker-compose exec postgres \
      sh -c 'while ! nc -z postgres 5432; do sleep 0.1; done'
  • Each of these deals with the database:
    • make postgres.data.delete to stop containers (notice the stop to the right of the colon) and clears data
    • make postgres.start to start the database in the background, and wait for it to start up

4. Migrations

migrations.blank: postgres.start
    docker-compose run worker \
      poetry run flask db revision

migrations.create: postgres.start
    docker-compose run worker \
      poetry run flask db migrate

migrations.upgrade: postgres.start
    docker-compose run worker \
      poetry run flask db upgrade

migrations.heads: postgres.start
    docker-compose run worker \
      poetry run flask db heads
  • Finally, each of these handles the usual migration tasks that a developer needs to do (note that each command starts postgres in the background with postgres.start):
    • make migrations.blank creates a blank Alembic migration
    • make migrations.create generates a migration off of any detected schema changes
    • make migrations.upgrade applies any unapplied migrations
    • make migrations.heads shows the latest the latest migration (and any forks in the migration path)

The Oldies Are Great

Makefiles may have been invented more than 40 years ago, but that doesn’t make them any less fit for the job. Using Make as the interface for project workflows allows for ease of knowledge sharing, quick onboarding of new developers, and straightforward refactoring use of other CLI tools.

And if you containerize your projects, onboarding engineers into a new project in any language just becomes:

  • Securely sharing credentials
  • Installing Make and Docker
  • Running make develop

So start building that new app you’ve been thinking about!

Links

  • Starter Repos
  • React-Flask Starter
  • Makefile example

Published at DZone with permission of Peter Valdez. See the original article here.

Opinions expressed by DZone contributors are their own.

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!