Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Next attempt to pull Agents into gems #1366

Merged
merged 6 commits into from
Jun 21, 2016

Conversation

dsander
Copy link
Collaborator

@dsander dsander commented Mar 23, 2016

The work is based on #920 and cantino/huginn_agent.

While I generally liked the idea of #1012 to add a "base agent" class which decouples the agent gems from active record it also added problems, for the specs to pass every method call that needs active record has to be mocked, stubbed or abstracted in the base agent class.

This attempt follows #920 by only moving the agent classes and specs into a gem and load them on startup. To ensure the agent gem works with Huginn I added a (at the moment messy) rake task which clones Huginn, injects the agent gem and runs the specs of the gem.

Running the tests on travis works as well: https://travis-ci.org/kreuzwerker/DKT.huginn_nlp_agents

The source of the gem can be viewed here, the only change needed was adding require 'huginn_agent/spec_helper' (which requires all files in spec/support/) to the agent specs.

The pull request to huginn_agent can be viewed here: huginn/huginn_agent#2

If we agree to follow this approach I am planning to make rake task universal and output more useful by shelling out using open3. Additionally adding a generator which creates the needed file structure for a new agent by running huginn_agent new awesome_agent would be cool.

Thanks to kreuzwerker.de who are paying me to work on this in the context of the research project 'Digitale Kuratierungstechnologien' of which they are a part of.

@davidwabnitz
Copy link

linking to discussion in #60

@cantino
Copy link
Member

cantino commented Mar 24, 2016

Very cool! I'll dig into this soon.

@dsander
Copy link
Collaborator Author

dsander commented Mar 30, 2016

I added a generator to the huginn_agent gem. huginn_agent new test_agent will create a new agent gem skeleton and attempt to add the needed .env configuration (assuming a .env was found in either ./huginn/.env, .env or ~/huginn/.env).
Running bundle and bundle exec rake inside the new agent directory should run the specs without issues.

@darrencauthon
Copy link
Contributor

While I generally liked the idea of #1012 to add a "base agent" class which decouples the agent gems from active record it also added problems, for the specs to pass every method call that needs active record has to be mocked, stubbed or abstracted in the base agent class.

Ah, just for the record... the problems you're associating with that approach are a byproduct of unit testing code, not of the approach to abstracting out the code into a base class. Even when I've written agents or contributed code to projects, I've had to use that same mock/stub/abstract approach to building my test scenarios. Like this:

https://github.com/cantino/huginn/pull/1209/files#diff-026ea14cf5cd2e2f57acd81960c31114R30

It's just my personal position on testing, and a conclusion I've come to after writing thousands upon thousands of tests. I know it's not shared by most Rails developers (Rails testing starts and ends with integration tests, even to the point that its concept of "unit tests" still hit the database), which is fine. We all pay the consequences of our own decisions, and I'm learning not to get worked up over these differences of view. 😄

I think that mocking and stubbing is great, as it frees me from the details that I don't care about -- like active record's serialization of hashes and the like. I'm using the framework, so I'm going to assume they work and instead focus on my code. I gain flexibility and simplicity in my tests, at the cost of the coverage that integration testing gives me.

Anyway, I just wanted to explain that bit. I really enjoyed the work I put into those pull requests, as they gave me a new look into abstracting by "projecting" an one thing (like my Rails-free BaseAgent) into an entirely different thing (like the Rails agent). Ruby is a very powerful and fun language! ⚡ ⚡ ⚡

I like your approach, it's a very neat idea. Good luck! 😄

@cantino
Copy link
Member

cantino commented Mar 31, 2016

I'm on vacation next week and looking forward to digging into this :)

@dsander dsander force-pushed the feature/agents_in_gems branch 2 times, most recently from 46ec385 to ce9ad90 Compare April 11, 2016 07:54
@cantino
Copy link
Member

cantino commented Apr 13, 2016

This took surprisingly little code!

@dsander
Copy link
Collaborator Author

dsander commented Apr 13, 2016

@cantino I was surprised as well, do you think the approach is worth pursuing?

@cantino
Copy link
Member

cantino commented Apr 14, 2016

It seems like it. The only real downside is that we lose the ability to update all Agents with a single commit, but since people may have private Agents, we don't really have that now anyway.

@dsander
Copy link
Collaborator Author

dsander commented Apr 14, 2016

I think we should keep our current agents in this repository and maybe move some with big dependencies into a agents directory like you did with the RssAgent in your PR.

What I am still uncertain about is how we will let the user add additional agent gems to the Gemfile. Something like HUGINN_AGENT_n=huginn_nlp_agents;~> 0.2.1;git://... could work.

@cantino
Copy link
Member

cantino commented Apr 16, 2016

You mean adding Agents in the Docker context?

@dsander
Copy link
Collaborator Author

dsander commented Apr 16, 2016

Yes for docker users the gems have to be configurable via the environment. For the other installation methods it would still be helpful otherwise you would need to maintain a small fork (even if the changes would just be in Gemfile*)

@cantino
Copy link
Member

cantino commented Apr 16, 2016

Hmm, good question.

I might suggest parens for the version strings.

HUGINN_ADDITIONAL_GEMS=huginn_nlp_agents(~> 0.2.1),huginn_slack,huginn_uber(> 1.0)

@dsander
Copy link
Collaborator Author

dsander commented Apr 16, 2016

That should work, maybe optional square brackets for a path or git url?

HUGINN_ADDITIONAL_GEMS=huginn_nlp_agents(~> 0.2.1)<git://github.com/...>,huginn_slack,huginn_uber(> 1.0)

@cantino
Copy link
Member

cantino commented Apr 16, 2016

Torn between that and something like

HUGINN_ADDITIONAL_GEMS=huginn_nlp_agents(v: ~> 0.2.1, url: git://github.com/...),huginn_slack,huginn_uber(v: > 1.0)

or even

HUGINN_ADDITIONAL_GEMS=huginn_nlp_agents(~> 0.2.1, git://github.com/...),huginn_slack(git@...),huginn_uber(> 1.0)

because we can probably detect a GIT / URL vs a version.

@dsander
Copy link
Collaborator Author

dsander commented Apr 19, 2016

I went with a more verbose version which allows possible arguments of the gem command. Did I forget cover a use case?

GEM_SEPARATOR = '\s*(?:,|\z)'.freeze
GEM_REGULAR_EXPRESSION = /(#{GEM_NAME})(?:\(#{GEM_OPTIONS}\)){0,1}#{GEM_SEPARATOR}/

def parse_agent_gems(string)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe parse_each_agent_gem(string)?

@dsander dsander changed the title WIP: Next attempt to pull Agents into gems Next attempt to pull Agents into gems Apr 21, 2016
@dsander
Copy link
Collaborator Author

dsander commented Apr 21, 2016

I would consider this feature complete now. Most of the changes are in huginn/huginn_agent#2. Maybe we should move the discussion over there and continue here after huginn_agent PR is merged?

@@ -192,3 +193,7 @@ end
if_true(ENV['DATABASE_ADAPTER'].strip == 'mysql2') do
gem 'mysql2', '~> 0.3.20'
end

GemfileHelper.parse_each_agent_gem(ENV['ADDITIOANL_GEMS']) do |args|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsander Just in case... should this be ADDITIONAL_GEMS?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes 😊, thanks!

@dsander dsander force-pushed the feature/agents_in_gems branch 2 times, most recently from 2d392c6 to 708106a Compare April 27, 2016 09:02
@dsander dsander force-pushed the feature/agents_in_gems branch 3 times, most recently from 0d24f5d to d830459 Compare June 20, 2016 09:20
@dsander
Copy link
Collaborator Author

dsander commented Jun 20, 2016

The specs are only failing because I bumped the huginn_agent version to 0.3.0 which is not release to rubygems yet. https://travis-ci.org/cantino/huginn/builds/138849715 is the last build.

@@ -19,8 +19,33 @@ def load_dotenv
)
end

GEM_NAME = '[A-Za-z0-9\.\-\_]+'.freeze
GEM_OPTIONS = '(.+?)\s*(?:,\s*(.+?)){0,1}'.freeze
GEM_SEPARATOR = '\s*(?:,|\z)'.freeze
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be \s*(?:,\s*|\z) in case there are spaces after the comma?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not needed, spaces are not valid in the GEM_NAME expression they will be .scan will skip over them and start the next match when any character that is allowed in GEM_NAME is found. In the specs gem are separated with spaces.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay!

@dsander dsander merged commit bba0e2e into huginn:master Jun 21, 2016
@dsander dsander deleted the feature/agents_in_gems branch June 21, 2016 08:47
@dsander
Copy link
Collaborator Author

dsander commented Jun 21, 2016

Merged! Thanks for the feedback and reviews!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants